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

Fix the panic when lpad/rpad parameter is negative #3829

Merged
merged 1 commit into from
Oct 17, 2022

Conversation

ZuoTiJia
Copy link
Contributor

@ZuoTiJia ZuoTiJia commented Oct 14, 2022

When I pass a negative parameter to the lpad function, it panics. Because the function will cast i64 to usize, which causes Vec to be unable to allocate enough memory, resulting in 'panic: capacity overflow'.

DataFusion CLI v13.0.0
❯ select lpad('abc', -1, 'abc');
thread 'main' panicked at 'capacity overflow', library/alloc/src/raw_vec.rs:518:5

I refer to the implementation of postgres, in postges, length is limited to i32, too large length will throw an error.

In psql 14.5

SELECT lpad('abc', 2147483647, 'abc');

ERROR: requested length too large

SELECT lpad('abc', -1);

lpad

------

(1 row)


At first I changed the function signature.

But after I changed the function signature, calling this function requires troublesome cast.

What changes are included in this PR?

So I can only change the inside of the function

if length < 0 length = 0;

if length > i32::MAX, an Error will be thrown

@github-actions github-actions bot added core Core DataFusion crate physical-expr Physical Expressions labels Oct 14, 2022
@ZuoTiJia ZuoTiJia changed the title Fix the panic when lpad/rpad parameter is -1 Fix the panic when lpad/rpad parameter is negative Oct 14, 2022
@ZuoTiJia
Copy link
Contributor Author

@alamb could you review?

let length = length as usize;
if length > i32::MAX as i64 {
return Err(DataFusionError::Internal(
"lpad requested length too large".to_string(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"lpad requested length too large".to_string(),
"rpad requested length too large".to_string(),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"lpad requested length too large".to_string(),
format!("rpad requested length {} too large", length),

let length = length as usize;
if length > i32::MAX as i64 {
return Err(DataFusionError::Internal(
"lpad requested length too large".to_string(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"lpad requested length too large".to_string(),
"rpad requested length too large".to_string(),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"lpad requested length too large".to_string(),
format!("rpad requested length {} too large", length),

Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great -- thank you @ZuoTiJia

let length = length as usize;
if length > i32::MAX as i64 {
return Err(DataFusionError::Internal(
"lpad requested length too large".to_string(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"lpad requested length too large".to_string(),
format!("lpad requested length {} too large", length),

let length = length as usize;
if length > i32::MAX as i64 {
return Err(DataFusionError::Internal(
"lpad requested length too large".to_string(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"lpad requested length too large".to_string(),
format!("rpad requested length {} too large", length),

let length = length as usize;
if length > i32::MAX as i64 {
return Err(DataFusionError::Internal(
"lpad requested length too large".to_string(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"lpad requested length too large".to_string(),
format!("rpad requested length {} too large", length),

* fix the panic when lpad/rpad parameter is negative

* add lpad/rpad test
Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great -- thanks @ZuoTiJia

Copy link
Member

@andygrove andygrove left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks @ZuoTiJia

@andygrove andygrove merged commit aec240f into apache:master Oct 17, 2022
@ursabot
Copy link

ursabot commented Oct 17, 2022

Benchmark runs are scheduled for baseline = 431a412 and contender = aec240f. aec240f is a master commit associated with this PR. Results will be available as each benchmark for each run completes.
Conbench compare runs links:
[Skipped ⚠️ Benchmarking of arrow-datafusion-commits is not supported on ec2-t3-xlarge-us-east-2] ec2-t3-xlarge-us-east-2
[Skipped ⚠️ Benchmarking of arrow-datafusion-commits is not supported on test-mac-arm] test-mac-arm
[Skipped ⚠️ Benchmarking of arrow-datafusion-commits is not supported on ursa-i9-9960x] ursa-i9-9960x
[Skipped ⚠️ Benchmarking of arrow-datafusion-commits is not supported on ursa-thinkcentre-m75q] ursa-thinkcentre-m75q
Buildkite builds:
Supported benchmarks:
ec2-t3-xlarge-us-east-2: Supported benchmark langs: Python, R. Runs only benchmarks with cloud = True
test-mac-arm: Supported benchmark langs: C++, Python, R
ursa-i9-9960x: Supported benchmark langs: Python, R, JavaScript
ursa-thinkcentre-m75q: Supported benchmark langs: C++, Java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Core DataFusion crate physical-expr Physical Expressions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants