MCPcopy Create free account
hub / github.com/dolthub/doltgresql / typeCheckSameTypedTupleExprs

Function typeCheckSameTypedTupleExprs

postgres/parser/sem/tree/type_check.go:2267–2323  ·  view source on GitHub ↗

typeCheckSameTypedTupleExprs type checks a list of expressions, asserting that all are tuples which have the same type or nulls. The function expects the first provided expression to be a tuple, and will panic if it is not. However, it does not expect all other expressions are tuples or nulls, and w

(
	ctx context.Context, semaCtx *SemaContext, desired *types.T, exprs ...Expr,
)

Source from the content-addressed store, hash-verified

2265// provided, which will hint that type which the expressions should resolve to,
2266// if possible.
2267func typeCheckSameTypedTupleExprs(
2268 ctx context.Context, semaCtx *SemaContext, desired *types.T, exprs ...Expr,
2269) ([]TypedExpr, *types.T, error) {
2270 // Hold the resolved type expressions of the provided exprs, in order.
2271 // TODO(nvanbenschoten): Look into reducing allocations here.
2272 typedExprs := make([]TypedExpr, len(exprs))
2273
2274 // All other exprs must be tuples.
2275 first := exprs[0].(*Tuple)
2276 if err := checkAllExprsAreTuplesOrNulls(ctx, semaCtx, exprs[1:]); err != nil {
2277 return nil, nil, err
2278 }
2279
2280 // All tuples must have the same length.
2281 firstLen := len(first.Exprs)
2282 if err := checkAllTuplesHaveLength(exprs[1:], firstLen); err != nil {
2283 return nil, nil, err
2284 }
2285
2286 // All expressions within tuples at the same indexes must be the same type.
2287 resTypes := types.MakeTuple(make([]*types.T, firstLen))
2288 sameTypeExprs := make([]Expr, 0, len(exprs))
2289 // We will be skipping nulls, so we need to keep track at which indices in
2290 // exprs are the non-null tuples.
2291 sameTypeExprsIndices := make([]int, 0, len(exprs))
2292 for elemIdx := range first.Exprs {
2293 sameTypeExprs = sameTypeExprs[:0]
2294 sameTypeExprsIndices = sameTypeExprsIndices[:0]
2295 for exprIdx, expr := range exprs {
2296 if expr == DNull {
2297 continue
2298 }
2299 sameTypeExprs = append(sameTypeExprs, expr.(*Tuple).Exprs[elemIdx])
2300 sameTypeExprsIndices = append(sameTypeExprsIndices, exprIdx)
2301 }
2302 desiredElem := types.Any
2303 if len(desired.TupleContents()) > elemIdx {
2304 desiredElem = desired.TupleContents()[elemIdx]
2305 }
2306 typedSubExprs, resType, err := TypeCheckSameTypedExprs(ctx, semaCtx, desiredElem, sameTypeExprs...)
2307 if err != nil {
2308 return nil, nil, pgerror.Newf(pgcode.DatatypeMismatch, "tuples %s are not the same type: %v", Exprs(exprs), err)
2309 }
2310 for j, typedExpr := range typedSubExprs {
2311 tupleIdx := sameTypeExprsIndices[j]
2312 exprs[tupleIdx].(*Tuple).Exprs[elemIdx] = typedExpr
2313 }
2314 resTypes.TupleContents()[elemIdx] = resType
2315 }
2316 for tupleIdx, expr := range exprs {
2317 if expr != DNull {
2318 expr.(*Tuple).typ = resTypes
2319 }
2320 typedExprs[tupleIdx] = expr.(TypedExpr)
2321 }
2322 return typedExprs, resTypes, nil
2323}
2324

Callers 1

TypeCheckSameTypedExprsFunction · 0.85

Calls 7

MakeTupleFunction · 0.92
NewfFunction · 0.92
checkAllTuplesHaveLengthFunction · 0.85
TypeCheckSameTypedExprsFunction · 0.85
ExprsTypeAlias · 0.85
TupleContentsMethod · 0.80

Tested by

no test coverage detected