Skip to content

Conversation

@rtpsw
Copy link
Contributor

@rtpsw rtpsw commented Oct 12, 2022

@rtpsw
Copy link
Contributor Author

rtpsw commented Oct 12, 2022

cc @icexelloss @westonpace

@pitrou
Copy link
Member

pitrou commented Oct 12, 2022

Same problem as #14347: this is basically adding a partial, incomplete guard for a condition the caller is supposed to check for themselves.

@pitrou
Copy link
Member

pitrou commented Oct 12, 2022

If we wanted to check that the ExecBatch values correspond to the Schema, we should check for schema equality on each of the Datum values. That can unfortunately be expensive.

@rtpsw
Copy link
Contributor Author

rtpsw commented Oct 12, 2022

Same problem as #14347: this is basically adding a partial, incomplete guard for a condition the caller is supposed to check for themselves.

If we wanted to check that the ExecBatch values corresponding to the Schema, we should check for schema equality on each of the Datum values. That can unfortunately be expensive.

To be sure, I understand that by partial incomplete guard you mean not checking for full schema equality. My goal here (and in the PR you linked) is not to fully guard, and I understand the cost of trying to do so. My goal is to avoid runtime crashes that are hard to debug when the cost of doing so is small. IMHO, this PR is a good tradeoff because it uses a cheap check to transform a crash failure to a raised error, which is easier to debug. I run into such crash failures while developing test cases. I agree that when a test case is correct then the failure cases do not occur, yet during development test cases are frequently not correct. Another reason is that developers of large apps would generally prefer an error the app can handle, and perhaps raise to its user, over crashing the app.

@pitrou
Copy link
Member

pitrou commented Oct 12, 2022

Another reason is that developers of large apps would generally prefer an error the app can handle, and perhaps raise to its user, over crashing the app.

I agree with this, but it is actually misleading here, because we're only checking a single condition and otherwise let errors crash silently (or corrupt memory etc.).

Copy link
Member

Choose a reason for hiding this comment

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

Why would this succeed and produce a truncated result here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This comment gives the background.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I checked this locally and it occurs in multiple places unfortunately. However, I don't think this is a behavior that we want to set in stone, so I think we should remove this particular test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll soon add a commit with checks showing the current situation, if only for posterity, and then I'll remove ones we do not want to keep.

@pitrou
Copy link
Member

pitrou commented Oct 12, 2022

Edit: if this avoids an immediate crash and allows you to see Validate failing afterwards, then I would be ok with this (but let's not silently truncate output columns either).

@rtpsw
Copy link
Contributor Author

rtpsw commented Oct 12, 2022

(but let's not silently truncate output columns either).

Before coding the condition if (static_cast<size_t>(schema->num_fields()) > values.size()) with > I tried coding it with != but got test failures elsewhere:

[ RUN      ] ExecPlanExecution.StressSourceOrderBy
/mnt/user1/tscontract/github/rtpsw/arrow/cpp/src/arrow/compute/exec/plan_test.cc:739: Failure
Failed
'_error_or_value56.status()' failed with Invalid: mismatching schema size
Google Test trace:
/mnt/user1/tscontract/github/rtpsw/arrow/cpp/src/arrow/compute/exec/plan_test.cc:720: single threaded
/mnt/user1/tscontract/github/rtpsw/arrow/cpp/src/arrow/compute/exec/plan_test.cc:717: unslowed
[  FAILED  ] ExecPlanExecution.StressSourceOrderBy (1 ms)

and

[ RUN      ] Substrait.BasicPlanRoundTrippingEndToEnd
/mnt/user1/tscontract/github/rtpsw/arrow/cpp/src/arrow/compute/exec/exec_plan.cc:58: Plan was destroyed before finishing
/mnt/user1/tscontract/github/rtpsw/arrow/cpp/src/arrow/engine/substrait/serde_test.cc:2083: Failure
Failed
'_error_or_value131.status()' failed with Invalid: mismatching schema size
[  FAILED  ] Substrait.BasicPlanRoundTrippingEndToEnd (1 ms)

If we'd like to fix these test failures, I'd suggest doing so separately.

@pitrou
Copy link
Member

pitrou commented Oct 12, 2022

@westonpace Are the failures mentioned above (mismatching schema size) legitimate?

@rtpsw
Copy link
Contributor Author

rtpsw commented Oct 12, 2022

Edit: if this avoids an immediate crash and allows you to see Validate failing afterwards, then I would be ok with this

With the current PR code, exec_batch.ToRecordBatch(reject_schema) just raises an error, i.e., it does not let an invalid record batch get created. Should I add some other check, and which?

@rtpsw
Copy link
Contributor Author

rtpsw commented Oct 12, 2022

@westonpace Are the failures mentioned above (mismatching schema size) legitimate?

Don't know yet; I'll need to examine. If I manage to do so quickly, I'll report here.

@rtpsw
Copy link
Contributor Author

rtpsw commented Oct 12, 2022

I agree with this, but it is actually misleading here, because we're only checking a single condition and otherwise let errors crash silently (or corrupt memory etc.).

I agree the leniency of the checks, as compared to validation, could be unexpected to some developers and therefore misleading. I'd suggest adding doc strings to clarify this. OTOH, I'm not sure which crash condition you mean could still occur. Since the current PR code check the number of values and their types before applying type-specific operations, I believe it can only crash on the DCHECK(false) line. I could fix this to return an error.

@pitrou
Copy link
Member

pitrou commented Oct 12, 2022

Ok, it looks like Acero relies on being able to silently truncate the number of fields in that method. Which is quite unfortunate.

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
DCHECK(false);
Unreachable();

Copy link
Member

Choose a reason for hiding this comment

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

Well, it's not really unreachable :-)

Copy link
Member

Choose a reason for hiding this comment

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

It would be a violation of ExecBatch's class invariant for the values to be other than Array or Scalar. Now that I'm looking for a statement of that invariant it's not easy to point at something, the closest I've got is in streaming_execution.rst. The constructor and ExecBatch::Make don't enforce this either. This validation should be explicit and centralized in ExecBatch

Copy link
Member

Choose a reason for hiding this comment

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

We should certainly add ExecBatch::Validate (and perhaps ExecBatch::ValidateFull).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm in favor of adding these validation methods - let's create a separate jira for this.

The constructor and ExecBatch::Make don't enforce this either.

Right. Also note that ExecBatch has public members, which various pieces of code access directly, so it can be easy to make it invalid.

Copy link
Member

Choose a reason for hiding this comment

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

Ok. Let's at least add a meaningful error message to the DCHECK :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Created https://issues.apache.org/jira/browse/ARROW-18015 for the validation. In the meantime, I added a meaningful error message.

@github-actions
Copy link

@github-actions
Copy link

⚠️ Ticket has not been started in JIRA, please click 'Start Progress'.

@rtpsw
Copy link
Contributor Author

rtpsw commented Oct 12, 2022

This comment applies to the commit I just pushed.

@rtpsw
Copy link
Contributor Author

rtpsw commented Oct 12, 2022

@pitrou, please let me know which checks to remove from the test.

@pitrou
Copy link
Member

pitrou commented Oct 13, 2022

@pitrou, please let me know which checks to remove from the test.

In the interest of moving this forward before 10.0.0, I pushed some changes myself.

Copy link
Member

@pitrou pitrou left a comment

Choose a reason for hiding this comment

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

Thanks a lot @rtpsw for persisting on this. Also sorry for the longish review process on this one.

@rtpsw
Copy link
Contributor Author

rtpsw commented Oct 13, 2022

Thanks @pitrou !

@pitrou
Copy link
Member

pitrou commented Oct 13, 2022

CI passed on @rtpsw 's fork.

@pitrou pitrou merged commit b5b41cc into apache:master Oct 13, 2022
@rtpsw rtpsw deleted the ARROW-18004 branch October 13, 2022 18:43
@ursabot
Copy link

ursabot commented Oct 14, 2022

Benchmark runs are scheduled for baseline = f3327d2 and contender = b5b41cc. b5b41cc is a master commit associated with this PR. Results will be available as each benchmark for each run completes.
Conbench compare runs links:
[Finished ⬇️0.0% ⬆️0.0%] ec2-t3-xlarge-us-east-2
[Failed ⬇️0.56% ⬆️0.0%] test-mac-arm
[Failed ⬇️0.0% ⬆️0.0%] ursa-i9-9960x
[Finished ⬇️0.82% ⬆️0.04%] ursa-thinkcentre-m75q
Buildkite builds:
[Finished] b5b41ccf ec2-t3-xlarge-us-east-2
[Failed] b5b41ccf test-mac-arm
[Failed] b5b41ccf ursa-i9-9960x
[Finished] b5b41ccf ursa-thinkcentre-m75q
[Finished] f3327d2c ec2-t3-xlarge-us-east-2
[Failed] f3327d2c test-mac-arm
[Failed] f3327d2c ursa-i9-9960x
[Finished] f3327d2c ursa-thinkcentre-m75q
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants