Fix prepare statement issue #9288
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What happens
The below query prepares a
SELECTstatement that contains two equal parameters. Both are referenced by$1. When preparing this statement, we first create aBoundParameterMapentry for the parameter into_years($1), with"1"as its identifier. This bound parameter entry hasreturn_type = UNKNOWN. Its respectiveBoundParameterExpressionalso hasreturn_type = UNKNOWN. Later, inAddCastToTypeInternal, we determine we know the return type of thisBoundParameterExpression, which isINTEGER. We adjust theBoundParameterExpressionand its corresponding entry in theBoundParameterMap.Now, when we bind the second parameter, we find the corresponding
BoundParameterMapentry because both have the same identifier.bound_expr->return_type = return_typesets the return type of thisBoundParameterExpressiontoUNKNOWN, which would potentially get propagated to the bind result and cause rebinding by thrown aParameterNotResolvedexception. However, because it is wrapped in a cast, this does not happen.Because we found a type for the first parameter occurrence, and the
CASTswallowed the second parameter occurrence, we later assumed that we do not have to rebind this prepared statement during execution. This leads to a leakingBoundParameterExpressionwith anUNKNOWNreturn type, which throwsINTERNAL Error: Invalid PhysicalType for GetTypeIdSize.Fix
My fix always determines if we previously found a type for a matching
BoundParameterMapentry (same identifier). If so, we always rebind when executing the prepared statement. This avoids leakingUNKNOWNtypes into execution by not rebinding. If there is a better/alternative solution to fix this, I am also very open to suggestions!