@@ -48,8 +48,7 @@ static unique_ptr<FunctionData> TextplotDensityBind(ClientContext &context, Scal
4848 throw BinderException (" tp_density takes at least one argument" );
4949 }
5050
51- auto source_type = LogicalType::LIST (LogicalType::DOUBLE);
52- auto &first_arg = arguments[0 ]->return_type ;
51+ const auto &first_arg = arguments[0 ]->return_type ;
5352 if (!first_arg.IsNested () || first_arg.InternalType () != PhysicalType::LIST ||
5453 !ListType::GetChildType (first_arg).IsNumeric ()) {
5554 throw InvalidTypeException (" tp_density first argument must be a list of numeric values" );
@@ -59,22 +58,22 @@ static unique_ptr<FunctionData> TextplotDensityBind(ClientContext &context, Scal
5958 int64_t width = 20 ;
6059 std::vector<std::string> graph_characters;
6160 string marker_char;
62- string style = " " ;
61+ string style;
6362
6463 for (idx_t i = 1 ; i < arguments.size (); i++) {
65- auto &arg = arguments[i];
64+ const auto &arg = arguments[i];
6665 if (arg->HasParameter ()) {
6766 throw ParameterNotResolvedException ();
6867 }
6968 if (!arg->IsFoldable ()) {
7069 throw BinderException (" tp_density: arguments must be constant" );
7170 }
72- auto &alias = arg->GetAlias ();
71+ const auto &alias = arg->GetAlias ();
7372 if (alias == " width" ) {
7473 if (!arg->return_type .IsIntegral ()) {
7574 throw BinderException (" tp_density: 'width' argument must be an integer" );
7675 }
77- auto eval_result = ExpressionExecutor::EvaluateScalar (context, *arg);
76+ const auto eval_result = ExpressionExecutor::EvaluateScalar (context, *arg);
7877 width = eval_result.CastAs (context, LogicalType::UBIGINT).GetValue <uint64_t >();
7978 } else if (alias == " marker" ) {
8079 if (arg->return_type .id () != LogicalTypeId::VARCHAR) {
@@ -86,16 +85,14 @@ static unique_ptr<FunctionData> TextplotDensityBind(ClientContext &context, Scal
8685 throw BinderException (" tp_density: 'graph_chars' argument must be a VARCHAR" );
8786 }
8887
89- child_list_t <LogicalType> children;
90-
9188 if (arg->return_type .InternalType () != PhysicalType::LIST) {
9289 throw BinderException (
9390 StringUtil::Format (" tp_density: 'graph_chars' argument must be a list of strings it is %s" ,
9491 arg->return_type .ToString ()));
9592 }
9693
97- auto list_children = ListValue::GetChildren (ExpressionExecutor::EvaluateScalar (context, *arg));
98- for (auto &list_item : list_children) {
94+ const auto list_children = ListValue::GetChildren (ExpressionExecutor::EvaluateScalar (context, *arg));
95+ for (const auto &list_item : list_children) {
9996 // These should also be lists.
10097 if (list_item.type () != LogicalType::VARCHAR) {
10198 throw BinderException (
@@ -121,8 +118,7 @@ static unique_ptr<FunctionData> TextplotDensityBind(ClientContext &context, Scal
121118
122119 if (!style.empty ()) {
123120 // lookup the style in density_sets
124- auto it = density_sets.find (style);
125- if (it != density_sets.end ()) {
121+ if (const auto it = density_sets.find (style); it != density_sets.end ()) {
126122 graph_characters = it->second ;
127123 } else {
128124 throw BinderException (StringUtil::Format (" tp_density: Unknown style '%s'" , style));
@@ -132,23 +128,23 @@ static unique_ptr<FunctionData> TextplotDensityBind(ClientContext &context, Scal
132128}
133129
134130inline void TextplotDensity (DataChunk &args, ExpressionState &state, Vector &result) {
135- auto &func_expr = state.expr .Cast <BoundFunctionExpression>();
131+ const auto &func_expr = state.expr .Cast <BoundFunctionExpression>();
136132 const auto &bind_data = func_expr.bind_info ->Cast <TextplotDensityBindData>();
137133
138134 auto &value_vector = args.data [0 ];
139135 Vector input_data (LogicalType::LIST (LogicalType::DOUBLE));
140136 VectorOperations::Cast (state.GetContext (), value_vector, input_data, args.size ());
141137
142- // auto list_entries = FlatVector::GetData<list_entry_t>(input_data);
143138 auto &child_data = ListVector::GetEntry (input_data);
144139 auto source_data = FlatVector::GetData<double >(child_data);
145140
146141 double markerValue = std::nan (" " );
147142
148143 UnaryExecutor::Execute<list_entry_t , string_t >(input_data, result, args.size (), [&](list_entry_t values) {
149144 std::vector<double > data_items;
145+ data_items.reserve (values.length );
150146
151- for (idx_t i = values.offset ; i < values.offset + values.length ; i++) {
147+ for (auto i = values.offset ; i < values.offset + values.length ; i++) {
152148 data_items.push_back (source_data[i]);
153149 }
154150
@@ -157,53 +153,51 @@ inline void TextplotDensity(DataChunk &args, ExpressionState &state, Vector &res
157153 }
158154
159155 // Find min and max values
160- auto minmax = std::minmax_element (data_items.begin (), data_items.end ());
161- double minVal = *minmax.first ;
162- double maxVal = *minmax.second ;
156+ const auto minmax = std::minmax_element (data_items.cbegin (), data_items.cend ());
157+ const double minVal = *minmax.first ;
158+ const double maxVal = *minmax.second ;
163159
164160 if (minVal == maxVal) {
165161 // All values are the same - use max density character
166- auto maxChar = bind_data.density_chars .back ();
167- vector<string> output_items;
168- for (idx_t i = 0 ; i < bind_data.width ; i++) {
169- output_items.push_back (maxChar);
170- }
162+ const auto &maxChar = bind_data.density_chars .back ();
163+ std::vector<string> output_items (bind_data.width , maxChar);
171164
172165 // Add marker if value matches
173- if (!std::isnan (markerValue) && std::abs (minVal - markerValue) < 1e-10 ) {
174- for (int i = 0 ; i < bind_data.width ; i++) {
175- output_items[i] = bind_data.marker_char ;
176- }
166+ if (!std::isnan (markerValue) && std::abs (minVal - markerValue) < 1e-10 && !bind_data.marker_char .empty ()) {
167+ std::fill (output_items.begin (), output_items.end (), bind_data.marker_char );
177168 }
178169
179170 // Now join all of the items without commas
180- std::string output_result = StringUtil::Join (output_items, " " );
171+ std::string output_result;
172+ for (const auto &item : output_items) {
173+ output_result += item;
174+ }
181175 return StringVector::AddString (result, output_result);
182176 }
183177
184178 // Create histogram bins
185179 std::vector<int > bins (bind_data.width , 0 );
186- double range = maxVal - minVal;
187- double binWidth = range / bind_data.width ;
180+ const double range = maxVal - minVal;
181+ const double binWidth = range / bind_data.width ;
188182
189183 // Count values in each bin
190- for (double val : data_items) {
191- int binIndex = static_cast <int >((val - minVal) / binWidth);
184+ for (const double val : data_items) {
185+ auto binIndex = static_cast <int >((val - minVal) / binWidth);
192186 if (binIndex >= bind_data.width )
193187 binIndex = bind_data.width - 1 ; // Handle edge case
194188 bins[binIndex]++;
195189 }
196190
197191 // Find max count for scaling
198- int maxCount = *std::max_element (bins.begin (), bins.end ());
192+ const int maxCount = *std::max_element (bins.cbegin (), bins.cend ());
199193 if (maxCount == 0 ) {
200- auto maxChar = bind_data.density_chars .front ();
201- vector< string> output_items ;
202- for (idx_t i = 0 ; i < bind_data.width ; i++) {
203- output_items. push_back ( maxChar) ;
194+ const auto & maxChar = bind_data.density_chars .front ();
195+ std:: string output_result ;
196+ for (int64_t i = 0 ; i < bind_data.width ; i++) {
197+ output_result += maxChar;
204198 }
205199
206- return StringVector::AddString (result, StringUtil::Join (output_items, " " ) );
200+ return StringVector::AddString (result, output_result );
207201 }
208202
209203 // Determine marker position if specified
@@ -216,16 +210,16 @@ inline void TextplotDensity(DataChunk &args, ExpressionState &state, Vector &res
216210
217211 // Generate ASCII representation using provided character set
218212 std::string output_result;
219- int numLevels = bind_data.density_chars .size () - 1 ;
213+ const int numLevels = bind_data.density_chars .size () - 1 ;
220214
221215 for (int i = 0 ; i < bind_data.width ; i++) {
222216 // Check if this position should have a marker
223- if (i == markerPos) {
217+ if (i == markerPos && !bind_data. marker_char . empty () ) {
224218 output_result += bind_data.marker_char ;
225219 } else {
226220 // Scale bin count to character range
227- double normalized = static_cast <double >(bins[i]) / maxCount;
228- int charIndex = static_cast <int >(normalized * numLevels + 0.5 );
221+ const auto normalized = static_cast <double >(bins[i]) / maxCount;
222+ auto charIndex = static_cast <int >(normalized * numLevels + 0.5 );
229223 charIndex = std::min (charIndex, numLevels);
230224 output_result += bind_data.density_chars [charIndex];
231225 }
@@ -269,7 +263,7 @@ struct TextplotBarBindData : public FunctionData {
269263
270264private:
271265 string get_char (const string &color, const string &default_color, const string &shape) const {
272- const std::unordered_map<std::string, std::string> *lookup_map;
266+ const std::unordered_map<std::string, std::string> *lookup_map = nullptr ;
273267 if (shape == " square" ) {
274268 lookup_map = &emoji_squares;
275269 } else if (shape == " circle" ) {
@@ -281,8 +275,7 @@ struct TextplotBarBindData : public FunctionData {
281275 }
282276
283277 if (!color.empty ()) {
284- auto it = lookup_map->find (color);
285- if (it != lookup_map->end ()) {
278+ if (const auto it = lookup_map->find (color); it != lookup_map->end ()) {
286279 return it->second ;
287280 } else {
288281 throw BinderException (StringUtil::Format (" tp_bar: Unknown color value '%s'" , color));
@@ -293,7 +286,7 @@ struct TextplotBarBindData : public FunctionData {
293286 }
294287
295288 std::string get_threshold_color (double n, const string &default_color) const {
296- if (thresholds.size () == 0 ) {
289+ if (thresholds.empty () ) {
297290 return default_color;
298291 }
299292 for (const auto &t : thresholds) {
@@ -356,47 +349,42 @@ static unique_ptr<FunctionData> TextplotBarBind(ClientContext &context, ScalarFu
356349 vector<std::pair<double , string>> thresholds;
357350
358351 for (idx_t i = 1 ; i < arguments.size (); i++) {
359- auto &arg = arguments[i];
352+ const auto &arg = arguments[i];
360353 if (arg->HasParameter ()) {
361354 throw ParameterNotResolvedException ();
362355 }
363356 if (!arg->IsFoldable ()) {
364357 throw BinderException (" tp_bar: arguments must be constant" );
365358 }
366- auto &alias = arg->GetAlias ();
359+ const auto &alias = arg->GetAlias ();
367360 if (alias == " min" ) {
368361 if (!arg->return_type .IsNumeric ()) {
369362 throw BinderException (" tp_bar: 'min' argument must be numeric" );
370363 }
371- auto eval_result = ExpressionExecutor::EvaluateScalar (context, *arg);
364+ const auto eval_result = ExpressionExecutor::EvaluateScalar (context, *arg);
372365 min = eval_result.CastAs (context, LogicalType::DOUBLE).GetValue <double >();
373366 } else if (alias == " max" ) {
374367 if (!arg->return_type .IsNumeric ()) {
375368 throw BinderException (" tp_bar: 'max' argument must be numeric" );
376369 }
377- auto eval_result = ExpressionExecutor::EvaluateScalar (context, *arg);
370+ const auto eval_result = ExpressionExecutor::EvaluateScalar (context, *arg);
378371 max = eval_result.CastAs (context, LogicalType::DOUBLE).GetValue <double >();
379372 } else if (alias == " thresholds" ) {
380- child_list_t <LogicalType> children;
381- children.push_back ({" threshold" , LogicalType::DOUBLE});
382- children.push_back ({" color" , LogicalType::VARCHAR});
383- auto threshold_record_type = LogicalType::STRUCT (children);
384-
385373 if (arg->return_type .InternalType () != PhysicalType::LIST) {
386374 throw BinderException (StringUtil::Format (
387375 " tp_bar: 'thresholds' argument must be a list of structs it is %s" , arg->return_type .ToString ()));
388376 }
389377
390- auto list_children = ListValue::GetChildren (ExpressionExecutor::EvaluateScalar (context, *arg));
391- for (auto &list_item : list_children) {
378+ const auto list_children = ListValue::GetChildren (ExpressionExecutor::EvaluateScalar (context, *arg));
379+ for (const auto &list_item : list_children) {
392380 // These should also be lists.
393381 if (list_item.type ().InternalType () != PhysicalType::STRUCT) {
394382 throw BinderException (
395383 StringUtil::Format (" tp_bar: 'thresholds' child must be a struct it is %s value is %s" ,
396384 list_item.type ().ToString (), list_item.ToString ()));
397385 }
398386 // Here you can extract the fields from the struct if needed.
399- auto struct_fields = StructValue::GetChildren (list_item);
387+ const auto struct_fields = StructValue::GetChildren (list_item);
400388 if (struct_fields.size () != 2 ) {
401389 throw BinderException (StringUtil::Format (
402390 " tp_bar: 'thresholds' child struct must have 2 fields it has %d" , struct_fields.size ()));
@@ -406,8 +394,8 @@ static unique_ptr<FunctionData> TextplotBarBind(ClientContext &context, ScalarFu
406394 " tp_bar: 'thresholds' child struct field 'threshold' must be numeric it is %s" ,
407395 struct_fields[0 ].type ().ToString ()));
408396 }
409- double threshold = struct_fields[0 ].CastAs (context, LogicalType::DOUBLE).GetValue <double >();
410- string color = struct_fields[1 ].CastAs (context, LogicalType::VARCHAR).GetValue <string>();
397+ const double threshold = struct_fields[0 ].CastAs (context, LogicalType::DOUBLE).GetValue <double >();
398+ const string color = struct_fields[1 ].CastAs (context, LogicalType::VARCHAR).GetValue <string>();
411399 thresholds.emplace_back (threshold, color);
412400 }
413401 std::sort (thresholds.begin (), thresholds.end (), [](const auto &a, const auto &b) {
@@ -417,10 +405,10 @@ static unique_ptr<FunctionData> TextplotBarBind(ClientContext &context, ScalarFu
417405 if (!arg->return_type .IsIntegral ()) {
418406 throw BinderException (" tp_bar: 'width' argument must be an integer" );
419407 }
420- auto eval_result = ExpressionExecutor::EvaluateScalar (context, *arg);
408+ const auto eval_result = ExpressionExecutor::EvaluateScalar (context, *arg);
421409 width = eval_result.CastAs (context, LogicalType::UBIGINT).GetValue <uint64_t >();
422410 } else if (alias == " filled" ) {
423- auto eval_result = ExpressionExecutor::EvaluateScalar (context, *arg);
411+ const auto eval_result = ExpressionExecutor::EvaluateScalar (context, *arg);
424412 filled = eval_result.CastAs (context, LogicalType::BOOLEAN).GetValue <bool >();
425413 } else if (alias == " on" ) {
426414 if (arg->return_type .id () != LogicalTypeId::VARCHAR) {
@@ -465,14 +453,15 @@ static unique_ptr<FunctionData> TextplotBarBind(ClientContext &context, ScalarFu
465453
466454inline void TextplotBar (DataChunk &args, ExpressionState &state, Vector &result) {
467455 auto &value_vector = args.data [0 ];
468- auto &func_expr = state.expr .Cast <BoundFunctionExpression>();
456+ const auto &func_expr = state.expr .Cast <BoundFunctionExpression>();
469457 const auto &bind_data = func_expr.bind_info ->Cast <TextplotBarBindData>();
470458
471459 UnaryExecutor::Execute<double , string_t >(value_vector, result, args.size (), [&](double value) {
472- auto proportion = std::clamp ((value - bind_data.min ) / (bind_data.max - bind_data.min ), 0.0 , 1.0 );
473- int64_t filled_blocks = static_cast <int64_t >(std::round (bind_data.width * proportion));
460+ const auto proportion = std::clamp ((value - bind_data.min ) / (bind_data.max - bind_data.min ), 0.0 , 1.0 );
461+ const auto filled_blocks = static_cast <int64_t >(std::round (bind_data.width * proportion));
474462
475463 string bar;
464+ bar.reserve (bind_data.width * 4 ); // Reserve space for potential multi-byte characters
476465 for (int64_t i = 0 ; i < bind_data.width ; i++) {
477466 if (bind_data.filled ) {
478467 // Fill all blocks up to the proportion
0 commit comments