MCPcopy Create free account
hub / github.com/auxten/postgresql-parser / makeEvalTupleIn

Function makeEvalTupleIn

pkg/sql/sem/tree/eval.go:2361–2424  ·  view source on GitHub ↗
(typ *types.T)

Source from the content-addressed store, hash-verified

2359}
2360
2361func makeEvalTupleIn(typ *types.T) *CmpOp {
2362 return &CmpOp{
2363 LeftType: typ,
2364 RightType: types.AnyTuple,
2365 Fn: func(ctx *EvalContext, arg, values Datum) (Datum, error) {
2366 vtuple := values.(*DTuple)
2367 // If the tuple was sorted during normalization, we can perform an
2368 // efficient binary search to find if the arg is in the tuple (as
2369 // long as the arg doesn't contain any NULLs).
2370 if len(vtuple.D) == 0 {
2371 // If the rhs tuple is empty, the result is always false (even if arg is
2372 // or contains NULL).
2373 return DBoolFalse, nil
2374 }
2375 if arg == DNull {
2376 return DNull, nil
2377 }
2378 argTuple, argIsTuple := arg.(*DTuple)
2379 if vtuple.Sorted() && !(argIsTuple && argTuple.ContainsNull()) {
2380 // The right-hand tuple is already sorted and contains no NULLs, and the
2381 // left side is not NULL (e.g. `NULL IN (1, 2)`) or a tuple that
2382 // contains NULL (e.g. `(1, NULL) IN ((1, 2), (3, 4))`).
2383 //
2384 // We can use binary search to make a determination in this case. This
2385 // is the common case when tuples don't contain NULLs.
2386 _, result := vtuple.SearchSorted(ctx, arg)
2387 return MakeDBool(DBool(result)), nil
2388 }
2389
2390 sawNull := false
2391 if !argIsTuple {
2392 // The left-hand side is not a tuple, e.g. `1 IN (1, 2)`.
2393 for _, val := range vtuple.D {
2394 if val == DNull {
2395 sawNull = true
2396 } else if val.Compare(ctx, arg) == 0 {
2397 return DBoolTrue, nil
2398 }
2399 }
2400 } else {
2401 // The left-hand side is a tuple, e.g. `(1, 2) IN ((1, 2), (3, 4))`.
2402 for _, val := range vtuple.D {
2403 if val == DNull {
2404 // We allow for a null value to be in the list of tuples, so we
2405 // need to check that upfront.
2406 sawNull = true
2407 } else {
2408 // Use the EQ function which properly handles NULLs.
2409 if res := cmpOpTupleFn(ctx, *argTuple, *val.(*DTuple), EQ); res == DNull {
2410 sawNull = true
2411 } else if res == DBoolTrue {
2412 return DBoolTrue, nil
2413 }
2414 }
2415 }
2416 }
2417 if sawNull {
2418 return DNull, nil

Callers 1

eval.goFile · 0.85

Calls 7

MakeDBoolFunction · 0.85
DBoolTypeAlias · 0.85
cmpOpTupleFnFunction · 0.85
SortedMethod · 0.80
ContainsNullMethod · 0.80
SearchSortedMethod · 0.80
CompareMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…