[repr types] eliminate noop casts (lowering impl)#34350
[repr types] eliminate noop casts (lowering impl)#34350mgree merged 8 commits intoMaterializeInc:mainfrom
Conversation
enable_cast_elimination) to elimi…|
My earlier attempt to do this (#27029) failed in part due to the adapter crate also calling MIR's |
|
I think so, but we won't know for sure until I rebase onto #34351 . |
|
Well, I'm seeing 6 calls to |
Got it, thank you! I'll prepare a separate PR that uses the HIR type, to avoid SQL/repr type confusion. |
b53d8e1 to
0174ba9
Compare
ded0f5f to
6f91e23
Compare
|
@ggevay I think this hits the notes we talked about on Wednesday morning---feature flag defaults to off, but we have some deliberate exposure to the flag being turned on in the freshmart SLT. (We could do more, if you think that's worth it!) |
ggevay
left a comment
There was a problem hiding this comment.
Looks great! I wrote some minor comments.
| Literal(datum, typ, _name) => SS::Literal(Ok(datum), typ), | ||
| CallUnmaterializable(func, _name) => SS::CallUnmaterializable(func), | ||
| CallUnary { | ||
| func: func::UnaryFunc::CastVarCharToString(_), |
There was a problem hiding this comment.
Later, when we have more casts that we want to remove, we could make this a configuration on the sqlfunc macro. But this is not so important for now.
src/adapter/src/catalog.rs
Outdated
| if let Ok(mut mir) = hir.lower_uncorrelated() { | ||
| if let Ok(mut mir) = | ||
| hir.lower_uncorrelated(catalog.system_config().enable_cast_elimination()) | ||
| { |
There was a problem hiding this comment.
Could the assert_eq!(mir_typ.scalar_type, return_styp); call a few lines below fail due to eliminating a cast here? For example when the function being tested is the cast function that we are removing.
There was a problem hiding this comment.
I turned it into a soft_assert_eq_or_log! with a message to help us figure things out if it fails. But also, this a test that we were already passing. (Is the smoketest generating random queries?)
There was a problem hiding this comment.
smoketest_fn generates very simple HIR expressions that just call a single function on some random parameters. It does this for almost all functions. I don't understand how we are passing this test: at some point it should generate an expression that simply calls this cast function that is being eliminated here, and then observe a type mismatch in this assert. Maybe it misses this function due to some unknown reason, or I am misunderstanding some type stuff.
Note that this kind of Rust tests uses the default of the flag from the Rust code, not the Python stuff. But I did try turning on your flag there and running this tests, and it passed. :confused-psyduck:
There was a problem hiding this comment.
It's because varchar_to_text is not a real function name---it's just generated from casts. So when we test every function in the catalog, we won't find varchar_to_text in PG_CATALOG_BUILTINS, so we won't test it.
I can change the test to ensure it's repr type correct, or I can leave it with the soft assert... the former shouldn't fail as we make more changes here, but it means things will stay silent. I'm tempted to leave the soft assert?
There was a problem hiding this comment.
Ok! Thanks for figuring it out!
Edit: I've added this here: https://github.com/MaterializeInc/database-issues/issues/8562
…nate varchar_to_text
…ult; add SLT test to ensure the transformation functions correctly
f489d82 to
d863d4e
Compare
The `varchar_to_text` cast is functionally a noop, but exists to satisfy the typechecker: `varchar(8)` and `varchar` and `text` are different SQL types. But they are _not_ different representation types---all of these will be `Datum::String` at runtime. So: in MIR, we can eliminate this cast. This PR alters lowering (gated behind the feature flag `enable_cast_elimination`) to not bother generating `varchar_to_text` when lowering HIR to MIR. ### Motivation * This PR adds a known-desirable feature. MaterializeInc#27239
As MIR moves to representation types (#34351), we must be careful to compute SQL types while we still have HIR. If we don't we run the risk of confusing clients who expected a `VARCHAR` column and got a `TEXT` column. (To be clear: the `Datum`s on the wire will always be the same, but the type metadata might be different. BI tools may get confused.) This PR increases confidence in the types we're presenting to users (and so confidence in repr-type optimizations like #34350). I'm happy to take suggestions on how best to add tests for this change---I think the right level is pgwire or even through a BI tool, but I'm not certain of the best way to build such a test. ### Motivation * This PR adds a known-desirable feature. #27239
The
varchar_to_textcast is functionally a noop, but exists to satisfy the typechecker:varchar(8)andvarcharandtextare different SQL types.But they are not different representation types---all of these will be
Datum::Stringat runtime. So: in MIR, we can eliminate this cast.This PR alters lowering (gated behind the feature flag
enable_cast_elimination) to not bother generatingvarchar_to_textwhen lowering HIR to MIR.Alternative implementation to #34348, which fails because the non-repr typechecker gets upset (and because I didn't rewrite the tests yet).
Both PRs will need to have only the repr typechecker running to avoid inconsistencies #34351.
Motivation
design doc: MIR typechecking using representation types #27239
Tips for reviewers
There's a lot of noise in the commits, since there are (it turns out) two lowering functions, one for possible correlated expressions and one for uncorrelated ones. The latter (
lower_uncorrelated) didn't take any configuration options, so there are many changes to accommodate the boolean flagenable_cast_elimination.Checklist
$T ⇔ Proto$Tmapping (possibly in a backwards-incompatible way), then it is tagged with aT-protolabel.