Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parquet RowGroup pruning for Dictionary(Decimal) type incorrect #13821

Open
korowa opened this issue Dec 17, 2024 · 2 comments
Open

parquet RowGroup pruning for Dictionary(Decimal) type incorrect #13821

korowa opened this issue Dec 17, 2024 · 2 comments
Assignees
Labels
bug Something isn't working

Comments

@korowa
Copy link
Contributor

korowa commented Dec 17, 2024

Describe the bug

Parquet RowGroup pruning by statistics works incorrectly for Dictionary(Decimal) type.

To Reproduce

use arrow;
use arrow::array::{ArrayRef, Decimal128Array, DictionaryArray, Int32Array, RecordBatch};
use datafusion::error::Result;
use datafusion::prelude::*;
use parquet::arrow::ArrowWriter;
use parquet::file::properties::{EnabledStatistics, WriterProperties};
use std::fs::File;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<()> {
    // Prepare record batch
    let array_values = Decimal128Array::from_iter_values(vec![10, 20, 30])
        .with_precision_and_scale(4, 1)?;
    let array_keys = Int32Array::from_iter_values(vec![0, 1, 2]);
    let array = Arc::new(DictionaryArray::new(array_keys, Arc::new(array_values)));
    let batch = RecordBatch::try_from_iter(vec![("col", array as ArrayRef)])?;

    // Write batch to parquet
    let file_path = "dictionary_decimal.parquet";

    let file = File::create(file_path)?;
    let properties = WriterProperties::builder()
        .set_statistics_enabled(EnabledStatistics::Chunk)
        .set_bloom_filter_enabled(true)
        .build();
    let mut writer = ArrowWriter::try_new(file, batch.schema(), Some(properties))?;

    writer.write(&batch)?;
    writer.flush()?;
    writer.close()?;

    // Prepare context
    let config = SessionConfig::default()
        .with_parquet_bloom_filter_pruning(true)
        .with_collect_statistics(true);
    let ctx = SessionContext::new_with_config(config);

    ctx.register_parquet("t", file_path, ParquetReadOptions::default())
        .await?;

    // In case pruning predicate not created (due to cast), there is a record in resultset
    ctx.sql("select * from t where col = 1")
        .await?
        .show()
        .await?;

    println!();

    // In case of triggered RowGroup pruning -- the only RowGroup eliminated while pruning by statistics
    ctx.sql("select * from t where col = cast(1 as decimal(4, 1))")
        .await?
        .show()
        .await?;

    Ok(())
}

Expected behavior

Results from both queries from the script above should match

Additional context

The problem also happens with bloom filters (if enable them in pattern matching expressions in prune_by_bloom_filters), so there is a chance that ArrowWriter produces incorrect metadata (statistics / bloom filters).

+ after adding larger value to the batch (like 100 as i128 which is 10.0 when casted to decimal(4, 1)), RG is not pruned, so perhaps something like * pow(10, scale) lost while writing statistics / calculating filters.

@korowa korowa added the bug Something isn't working label Dec 17, 2024
@alamb alamb changed the title parquet RowGroup pruning for Dictionary(Decimal) type parquet RowGroup pruning for Dictionary(Decimal) type incorreft Dec 17, 2024
@alamb alamb changed the title parquet RowGroup pruning for Dictionary(Decimal) type incorreft parquet RowGroup pruning for Dictionary(Decimal) type incorrect Dec 17, 2024
@kosiew
Copy link
Contributor

kosiew commented Dec 20, 2024

Research findings:

with parquest_pruning turned off

    let config = SessionConfig::default()
        .with_parquet_bloom_filter_pruning(true)
        .with_parquet_pruning(false) 
        .with_collect_statistics(true);

both queries return the same result:

+-----+
| col |
+-----+
| 1.0 |
+-----+

@lichuang
Copy link

take

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants