Skip to content

Commit e23d34b

Browse files
authored
Support SHOW ALL VERBOSE to show settings description (#7735)
* Expand SHOW ALL stmt to show settings description * cli tests * comments
1 parent 093b775 commit e23d34b

File tree

6 files changed

+149
-25
lines changed

6 files changed

+149
-25
lines changed

datafusion-cli/tests/cli_integration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn init() {
4343
)]
4444
#[case::set_batch_size(
4545
["--command", "show datafusion.execution.batch_size", "--format", "json", "-q", "-b", "1"],
46-
"[{\"name\":\"datafusion.execution.batch_size\",\"setting\":\"1\"}]\n"
46+
"[{\"name\":\"datafusion.execution.batch_size\",\"value\":\"1\"}]\n"
4747
)]
4848
#[test]
4949
fn cli_quick_test<'a>(

datafusion/core/src/catalog/information_schema.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,8 @@ impl InformationSchemaDfSettings {
626626
fn new(config: InformationSchemaConfig) -> Self {
627627
let schema = Arc::new(Schema::new(vec![
628628
Field::new("name", DataType::Utf8, false),
629-
Field::new("setting", DataType::Utf8, true),
629+
Field::new("value", DataType::Utf8, true),
630+
Field::new("description", DataType::Utf8, true),
630631
]));
631632

632633
Self { schema, config }
@@ -635,7 +636,8 @@ impl InformationSchemaDfSettings {
635636
fn builder(&self) -> InformationSchemaDfSettingsBuilder {
636637
InformationSchemaDfSettingsBuilder {
637638
names: StringBuilder::new(),
638-
settings: StringBuilder::new(),
639+
values: StringBuilder::new(),
640+
descriptions: StringBuilder::new(),
639641
schema: self.schema.clone(),
640642
}
641643
}
@@ -664,21 +666,24 @@ impl PartitionStream for InformationSchemaDfSettings {
664666
struct InformationSchemaDfSettingsBuilder {
665667
schema: SchemaRef,
666668
names: StringBuilder,
667-
settings: StringBuilder,
669+
values: StringBuilder,
670+
descriptions: StringBuilder,
668671
}
669672

670673
impl InformationSchemaDfSettingsBuilder {
671674
fn add_setting(&mut self, entry: ConfigEntry) {
672675
self.names.append_value(entry.key);
673-
self.settings.append_option(entry.value);
676+
self.values.append_option(entry.value);
677+
self.descriptions.append_value(entry.description);
674678
}
675679

676680
fn finish(&mut self) -> RecordBatch {
677681
RecordBatch::try_new(
678682
self.schema.clone(),
679683
vec![
680684
Arc::new(self.names.finish()),
681-
Arc::new(self.settings.finish()),
685+
Arc::new(self.values.finish()),
686+
Arc::new(self.descriptions.finish()),
682687
],
683688
)
684689
.unwrap()

datafusion/sql/src/statement.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -757,28 +757,34 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
757757
}
758758

759759
fn show_variable_to_plan(&self, variable: &[Ident]) -> Result<LogicalPlan> {
760-
let variable = object_name_to_string(&ObjectName(variable.to_vec()));
761-
762760
if !self.has_table("information_schema", "df_settings") {
763761
return plan_err!(
764762
"SHOW [VARIABLE] is not supported unless information_schema is enabled"
765763
);
766764
}
767765

768-
let variable_lower = variable.to_lowercase();
766+
let verbose = variable
767+
.last()
768+
.map(|s| ident_to_string(s) == "verbose")
769+
.unwrap_or(false);
770+
let mut variable_vec = variable.to_vec();
771+
let mut columns: String = "name, value".to_owned();
772+
773+
if verbose {
774+
columns = format!("{columns}, description");
775+
variable_vec = variable_vec.split_at(variable_vec.len() - 1).0.to_vec();
776+
}
769777

770-
let query = if variable_lower == "all" {
778+
let variable = object_name_to_string(&ObjectName(variable_vec));
779+
let base_query = format!("SELECT {columns} FROM information_schema.df_settings");
780+
let query = if variable == "all" {
771781
// Add an ORDER BY so the output comes out in a consistent order
772-
String::from(
773-
"SELECT name, setting FROM information_schema.df_settings ORDER BY name",
774-
)
775-
} else if variable_lower == "timezone" || variable_lower == "time.zone" {
782+
format!("{base_query} ORDER BY name")
783+
} else if variable == "timezone" || variable == "time.zone" {
776784
// we could introduce alias in OptionDefinition if this string matching thing grows
777-
String::from("SELECT name, setting FROM information_schema.df_settings WHERE name = 'datafusion.execution.time_zone'")
785+
format!("{base_query} WHERE name = 'datafusion.execution.time_zone'")
778786
} else {
779-
format!(
780-
"SELECT name, setting FROM information_schema.df_settings WHERE name = '{variable}'"
781-
)
787+
format!("{base_query} WHERE name = '{variable}'")
782788
};
783789

784790
let mut rewrite = DFParser::parse_sql(&query)?;

datafusion/sqllogictest/test_files/information_schema.slt

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,85 @@ datafusion.sql_parser.dialect generic
202202
datafusion.sql_parser.enable_ident_normalization true
203203
datafusion.sql_parser.parse_float_as_decimal false
204204

205+
# show all variables with verbose
206+
query TTT rowsort
207+
SHOW ALL VERBOSE
208+
----
209+
datafusion.catalog.create_default_catalog_and_schema true Whether the default catalog and schema should be created automatically.
210+
datafusion.catalog.default_catalog datafusion The default catalog name - this impacts what SQL queries use if not specified
211+
datafusion.catalog.default_schema public The default schema name - this impacts what SQL queries use if not specified
212+
datafusion.catalog.format NULL Type of `TableProvider` to use when loading `default` schema
213+
datafusion.catalog.has_header false If the file has a header
214+
datafusion.catalog.information_schema true Should DataFusion provide access to `information_schema` virtual tables for displaying schema information
215+
datafusion.catalog.location NULL Location scanned to load tables for `default` schema
216+
datafusion.execution.aggregate.scalar_update_factor 10 Specifies the threshold for using `ScalarValue`s to update accumulators during high-cardinality aggregations for each input batch. The aggregation is considered high-cardinality if the number of affected groups is greater than or equal to `batch_size / scalar_update_factor`. In such cases, `ScalarValue`s are utilized for updating accumulators, rather than the default batch-slice approach. This can lead to performance improvements. By adjusting the `scalar_update_factor`, you can balance the trade-off between more efficient accumulator updates and the number of groups affected.
217+
datafusion.execution.batch_size 8192 Default batch size while creating new batches, it's especially useful for buffer-in-memory batches since creating tiny batches would result in too much metadata memory consumption
218+
datafusion.execution.coalesce_batches true When set to true, record batches will be examined between each operator and small batches will be coalesced into larger batches. This is helpful when there are highly selective filters or joins that could produce tiny output batches. The target batch size is determined by the configuration setting
219+
datafusion.execution.collect_statistics false Should DataFusion collect statistics after listing files
220+
datafusion.execution.meta_fetch_concurrency 32 Number of files to read in parallel when inferring schema and statistics
221+
datafusion.execution.parquet.allow_single_file_parallelism false Controls whether DataFusion will attempt to speed up writing large parquet files by first writing multiple smaller files and then stitching them together into a single large file. This will result in faster write speeds, but higher memory usage. Also currently unsupported are bloom filters and column indexes when single_file_parallelism is enabled.
222+
datafusion.execution.parquet.bloom_filter_enabled false Sets if bloom filter is enabled for any column
223+
datafusion.execution.parquet.bloom_filter_fpp NULL Sets bloom filter false positive probability. If NULL, uses default parquet writer setting
224+
datafusion.execution.parquet.bloom_filter_ndv NULL Sets bloom filter number of distinct values. If NULL, uses default parquet writer setting
225+
datafusion.execution.parquet.column_index_truncate_length NULL Sets column index trucate length
226+
datafusion.execution.parquet.compression zstd(3) Sets default parquet compression codec Valid values are: uncompressed, snappy, gzip(level), lzo, brotli(level), lz4, zstd(level), and lz4_raw. These values are not case sensitive. If NULL, uses default parquet writer setting
227+
datafusion.execution.parquet.created_by datafusion Sets "created by" property
228+
datafusion.execution.parquet.data_page_row_count_limit 18446744073709551615 Sets best effort maximum number of rows in data page
229+
datafusion.execution.parquet.data_pagesize_limit 1048576 Sets best effort maximum size of data page in bytes
230+
datafusion.execution.parquet.dictionary_enabled NULL Sets if dictionary encoding is enabled. If NULL, uses default parquet writer setting
231+
datafusion.execution.parquet.dictionary_page_size_limit 1048576 Sets best effort maximum dictionary page size, in bytes
232+
datafusion.execution.parquet.enable_page_index true If true, reads the Parquet data page level metadata (the Page Index), if present, to reduce the I/O and number of rows decoded.
233+
datafusion.execution.parquet.encoding NULL Sets default encoding for any column Valid values are: plain, plain_dictionary, rle, bit_packed, delta_binary_packed, delta_length_byte_array, delta_byte_array, rle_dictionary, and byte_stream_split. These values are not case sensitive. If NULL, uses default parquet writer setting
234+
datafusion.execution.parquet.max_row_group_size 1048576 Sets maximum number of rows in a row group
235+
datafusion.execution.parquet.max_statistics_size NULL Sets max statistics size for any column. If NULL, uses default parquet writer setting
236+
datafusion.execution.parquet.metadata_size_hint NULL If specified, the parquet reader will try and fetch the last `size_hint` bytes of the parquet file optimistically. If not specified, two reads are required: One read to fetch the 8-byte parquet footer and another to fetch the metadata length encoded in the footer
237+
datafusion.execution.parquet.pruning true If true, the parquet reader attempts to skip entire row groups based on the predicate in the query and the metadata (min/max values) stored in the parquet file
238+
datafusion.execution.parquet.pushdown_filters false If true, filter expressions are be applied during the parquet decoding operation to reduce the number of rows decoded
239+
datafusion.execution.parquet.reorder_filters false If true, filter expressions evaluated during the parquet decoding operation will be reordered heuristically to minimize the cost of evaluation. If false, the filters are applied in the same order as written in the query
240+
datafusion.execution.parquet.skip_metadata true If true, the parquet reader skip the optional embedded metadata that may be in the file Schema. This setting can help avoid schema conflicts when querying multiple parquet files with schemas containing compatible types but different metadata
241+
datafusion.execution.parquet.statistics_enabled NULL Sets if statistics are enabled for any column Valid values are: "none", "chunk", and "page" These values are not case sensitive. If NULL, uses default parquet writer setting
242+
datafusion.execution.parquet.write_batch_size 1024 Sets write_batch_size in bytes
243+
datafusion.execution.parquet.writer_version 1.0 Sets parquet writer version valid values are "1.0" and "2.0"
244+
datafusion.execution.planning_concurrency 13 Fan-out during initial physical planning. This is mostly use to plan `UNION` children in parallel. Defaults to the number of CPU cores on the system
245+
datafusion.execution.sort_in_place_threshold_bytes 1048576 When sorting, below what size should data be concatenated and sorted in a single RecordBatch rather than sorted in batches and merged.
246+
datafusion.execution.sort_spill_reservation_bytes 10485760 Specifies the reserved memory for each spillable sort operation to facilitate an in-memory merge. When a sort operation spills to disk, the in-memory data must be sorted and merged before being written to a file. This setting reserves a specific amount of memory for that in-memory sort/merge process. Note: This setting is irrelevant if the sort operation cannot spill (i.e., if there's no `DiskManager` configured).
247+
datafusion.execution.target_partitions 7 Number of partitions for query execution. Increasing partitions can increase concurrency. Defaults to the number of CPU cores on the system
248+
datafusion.execution.time_zone +00:00 The default time zone Some functions, e.g. `EXTRACT(HOUR from SOME_TIME)`, shift the underlying datetime according to this time zone, and then extract the hour
249+
datafusion.explain.logical_plan_only false When set to true, the explain statement will only print logical plans
250+
datafusion.explain.physical_plan_only false When set to true, the explain statement will only print physical plans
251+
datafusion.explain.show_statistics false When set to true, the explain statement will print operator statistics for physical plans
252+
datafusion.optimizer.allow_symmetric_joins_without_pruning true Should DataFusion allow symmetric hash joins for unbounded data sources even when its inputs do not have any ordering or filtering If the flag is not enabled, the SymmetricHashJoin operator will be unable to prune its internal buffers, resulting in certain join types - such as Full, Left, LeftAnti, LeftSemi, Right, RightAnti, and RightSemi - being produced only at the end of the execution. This is not typical in stream processing. Additionally, without proper design for long runner execution, all types of joins may encounter out-of-memory errors.
253+
datafusion.optimizer.enable_round_robin_repartition true When set to true, the physical plan optimizer will try to add round robin repartitioning to increase parallelism to leverage more CPU cores
254+
datafusion.optimizer.enable_topk_aggregation true When set to true, the optimizer will attempt to perform limit operations during aggregations, if possible
255+
datafusion.optimizer.filter_null_join_keys false When set to true, the optimizer will insert filters before a join between a nullable and non-nullable column to filter out nulls on the nullable side. This filter can add additional overhead when the file format does not fully support predicate push down.
256+
datafusion.optimizer.hash_join_single_partition_threshold 1048576 The maximum estimated size in bytes for one input side of a HashJoin will be collected into a single partition
257+
datafusion.optimizer.max_passes 3 Number of times that the optimizer will attempt to optimize the plan
258+
datafusion.optimizer.prefer_existing_sort false When true, DataFusion will opportunistically remove sorts when the data is already sorted, (i.e. setting `preserve_order` to true on `RepartitionExec` and using `SortPreservingMergeExec`) When false, DataFusion will maximize plan parallelism using `RepartitionExec` even if this requires subsequently resorting data using a `SortExec`.
259+
datafusion.optimizer.prefer_hash_join true When set to true, the physical plan optimizer will prefer HashJoin over SortMergeJoin. HashJoin can work more efficiently than SortMergeJoin but consumes more memory
260+
datafusion.optimizer.repartition_aggregations true Should DataFusion repartition data using the aggregate keys to execute aggregates in parallel using the provided `target_partitions` level
261+
datafusion.optimizer.repartition_file_min_size 10485760 Minimum total files size in bytes to perform file scan repartitioning.
262+
datafusion.optimizer.repartition_file_scans true When set to `true`, file groups will be repartitioned to achieve maximum parallelism. Currently Parquet and CSV formats are supported. If set to `true`, all files will be repartitioned evenly (i.e., a single large file might be partitioned into smaller chunks) for parallel scanning. If set to `false`, different files will be read in parallel, but repartitioning won't happen within a single file.
263+
datafusion.optimizer.repartition_joins true Should DataFusion repartition data using the join keys to execute joins in parallel using the provided `target_partitions` level
264+
datafusion.optimizer.repartition_sorts true Should DataFusion execute sorts in a per-partition fashion and merge afterwards instead of coalescing first and sorting globally. With this flag is enabled, plans in the form below ```text "SortExec: [a@0 ASC]", " CoalescePartitionsExec", " RepartitionExec: partitioning=RoundRobinBatch(8), input_partitions=1", ``` would turn into the plan below which performs better in multithreaded environments ```text "SortPreservingMergeExec: [a@0 ASC]", " SortExec: [a@0 ASC]", " RepartitionExec: partitioning=RoundRobinBatch(8), input_partitions=1", ```
265+
datafusion.optimizer.repartition_windows true Should DataFusion repartition data using the partitions keys to execute window functions in parallel using the provided `target_partitions` level
266+
datafusion.optimizer.skip_failed_rules false When set to true, the logical plan optimizer will produce warning messages if any optimization rules produce errors and then proceed to the next rule. When set to false, any rules that produce errors will cause the query to fail
267+
datafusion.optimizer.top_down_join_key_reordering true When set to true, the physical plan optimizer will run a top down process to reorder the join keys
268+
datafusion.sql_parser.dialect generic Configure the SQL dialect used by DataFusion's parser; supported values include: Generic, MySQL, PostgreSQL, Hive, SQLite, Snowflake, Redshift, MsSQL, ClickHouse, BigQuery, and Ansi.
269+
datafusion.sql_parser.enable_ident_normalization true When set to true, SQL parser will normalize ident (convert ident to lowercase when not quoted)
270+
datafusion.sql_parser.parse_float_as_decimal false When set to true, SQL parser will parse float as decimal type
271+
205272
# show_variable_in_config_options
206273
query TT
207274
SHOW datafusion.execution.batch_size
208275
----
209276
datafusion.execution.batch_size 8192
210277

278+
# show_variable_in_config_options_verbose
279+
query TTT
280+
SHOW datafusion.execution.batch_size VERBOSE
281+
----
282+
datafusion.execution.batch_size 8192 Default batch size while creating new batches, it's especially useful for buffer-in-memory batches since creating tiny batches would result in too much metadata memory consumption
283+
211284
# show_time_zone_default_utc
212285
# https://github.com/apache/arrow-datafusion/issues/3255
213286
query TT
@@ -223,6 +296,26 @@ SHOW TIMEZONE
223296
datafusion.execution.time_zone +00:00
224297

225298

299+
# show_time_zone_default_utc_verbose
300+
# https://github.com/apache/arrow-datafusion/issues/3255
301+
query TTT
302+
SHOW TIME ZONE VERBOSE
303+
----
304+
datafusion.execution.time_zone +00:00 The default time zone Some functions, e.g. `EXTRACT(HOUR from SOME_TIME)`, shift the underlying datetime according to this time zone, and then extract the hour
305+
306+
# show_timezone_default_utc
307+
# https://github.com/apache/arrow-datafusion/issues/3255
308+
query TTT
309+
SHOW TIMEZONE VERBOSE
310+
----
311+
datafusion.execution.time_zone +00:00 The default time zone Some functions, e.g. `EXTRACT(HOUR from SOME_TIME)`, shift the underlying datetime according to this time zone, and then extract the hour
312+
313+
314+
# show empty verbose
315+
query TTT
316+
SHOW VERBOSE
317+
----
318+
226319
# information_schema_describe_table
227320

228321
## some_table
@@ -372,6 +465,9 @@ set datafusion.catalog.information_schema = false;
372465
statement error Error during planning: SHOW \[VARIABLE\] is not supported unless information_schema is enabled
373466
SHOW SOMETHING
374467

468+
statement error Error during planning: SHOW \[VARIABLE\] is not supported unless information_schema is enabled
469+
SHOW SOMETHING VERBOSE
470+
375471
statement ok
376472
set datafusion.catalog.information_schema = true;
377473

datafusion/sqllogictest/test_files/set_variable.slt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,4 +243,4 @@ statement ok
243243
SET TIME ZONE = 'Asia/Taipei2'
244244

245245
statement error Arrow error: Parser error: Invalid timezone "Asia/Taipei2": 'Asia/Taipei2' is not a valid timezone
246-
SELECT '2000-01-01T00:00:00'::TIMESTAMP::TIMESTAMPTZ
246+
SELECT '2000-01-01T00:00:00'::TIMESTAMP::TIMESTAMPTZ

0 commit comments

Comments
 (0)