SPI_CURS...WITH_ARGS(3)

πŸ“¦ version 17.11, in opensuse-leap 16.0

✨ SPI_CURS...WITH_ARGS ✨

okay so bestie, buckle up, we're in the PostgreSQL 17.11 docs, section 3 β€” the C-functions-for-server-programmers zone πŸ’… this one's called SPI_cursor_open_with_args, and it's literally the "open a cursor with args in one shot" girlie. no cap.


🌸 NAME 🌸

SPI_cursor_open_with_args β€” set up a cursor using a query and parameters πŸŽ€


✨ SYNOPSIS ✨

Portal SPI_cursor_open_with_args(const char *name,
                                 const char *command,
                                 int nargs, Oid *argtypes,
                                 Datum *values, const char *nulls,
                                 bool read_only, int cursorOptions)

she takes a lot of arguments, i know, but it's giving "one function to rule them all" energy πŸ‘‘


πŸ’– DESCRIPTION πŸ’–

so SPI_cursor_open_with_args sets up a cursor (internally, a portal, iykyk) that will execute the query you hand it. πŸ¦‹ most of the parameters mean the exact same thing as the corresponding parameters to SPI_prepare_cursor and SPI_cursor_open β€” like, same vibes, same semantics, no plot twist.

for one-time query execution, this function is the one you should prefer over SPI_prepare_cursor followed by SPI_cursor_open. like, just use the cute combined one, bestie 🫢 but β€” and this is important β€” if the same command is gonna be executed with many different parameters, either method might be faster, depending on the cost of re-planning versus the benefit of custom plans. so it's genuinely a "it depends" situation, not a "one is always better" situation. ngl that's just how it is 😭

the passed-in parameter data will be copied into the cursor's portal, so you can free it while the cursor still exists. yes, really β€” free it, she's got her own copy, she doesn't need yours anymore ✨

πŸ’€ deprecation warning, bestie: this function is now deprecated in favor of SPI_cursor_parse_open, which provides equivalent functionality using a more modern API for handling query parameters. so like... she still works, but she's lowkey the older sister who's been replaced by a cooler, more modern API. use SPI_cursor_parse_open for new stuff, periodt.

πŸŽ€ ARGUMENTS πŸŽ€

  • const char * name β€” name for the portal, or NULL to let the system select a name for you. the system's got taste, she'll pick something 🧚
  • const char * command β€” the command string itself. the actual query, the main character of this whole operation πŸ‘‘
  • int nargs β€” number of input parameters ($1, $2, etc.). count them carefully bestie, no cap πŸ”₯
  • Oid * argtypes β€” an array of length nargs, containing the OIDs of the data types of the parameters. so like, one Oid per parameter, in order, don't skip any 🌈
  • Datum * values β€” an array of length nargs, containing the actual parameter values. the real ones. the content πŸ’œ
  • const char * nulls β€” an array of length nargs, describing which parameters are null. this is the spicy one, so listen up πŸ™ˆ

If nulls is NULL then SPI_cursor_open_with_args assumes that no parameters are null. otherwise, each entry of the nulls array should be ' ' if the corresponding parameter value is non-null, or 'n' if the corresponding parameter value is null. (in the latter case, the actual value in the corresponding values entry doesn't matter β€” it's literally being ignored, she doesn't care πŸ’€)

and this is the part everyone gets wrong: note that nulls is not a text string, just an array β€” it does not need a '\0' terminator. don't add one. she's built different πŸ¦‹

  • bool read_only β€” true for read-only execution. set it to true and she'll behave πŸŽ€
  • int cursorOptions β€” integer bit mask of cursor options; zero produces default behavior. zero = default vibes, no notes ✨

πŸ‘‘ RETURN VALUE πŸ‘‘

pointer to the portal containing the cursor. 🫢

and like... note there is no error return convention β€” any error will be reported via elog. so don't go checking for NULL expecting a cute little error signal, because that's not how she rolls. if something goes wrong, elog is gonna yell about it, not return a value. fr fr 😭


πŸ’‘ tiny reminder from your girl: this is the deprecated one, so if you're starting fresh, SPI_cursor_parse_open is right there waiting for you. iykyk πŸ’…

okay that's the whole page!! huge shoutout to the PostgreSQL 17.11 docs crew, this page is dated 2026, and the manual section is SPI_CURS...WITH_ARGS(3) β€” mwah, love you, go write some slay server-side C code for me πŸ’–βœ¨πŸŽ€πŸ¦‹πŸŒΈπŸ’…πŸ«Ά

πŸ“¦ where this page comes from