agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH v1] Replace the char to bool array for null parameters 24+ messages / 2 participants [nested] [flat]
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* [PATCH v1] Replace the char to bool array for null parameters @ 2021-01-19 07:51 Japin Li <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: Japin Li @ 2021-01-19 07:51 UTC (permalink / raw) --- doc/src/sgml/spi.sgml | 60 ++++++++++++----------------- src/backend/executor/spi.c | 18 ++++----- src/backend/utils/adt/ri_triggers.c | 8 ++-- src/backend/utils/adt/ruleutils.c | 10 ++--- src/include/executor/spi.h | 12 +++--- src/pl/plperl/plperl.c | 6 +-- src/pl/plpython/plpy_cursorobject.c | 6 +-- src/test/regress/regress.c | 12 +++--- 8 files changed, 61 insertions(+), 71 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index f5e0a35da0..d3cc405c42 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -649,7 +649,7 @@ int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count< <synopsis> int SPI_execute_with_args(const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -728,7 +728,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -739,12 +739,10 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1601,7 +1599,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>) <refsynopsisdiv> <synopsis> -int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, +int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1642,7 +1640,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1653,12 +1651,10 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execute_plan</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -1946,7 +1942,7 @@ int SPI_execute_plan_with_receiver(SPIPlanPtr <parameter>plan</parameter>, <refsynopsisdiv> <synopsis> -int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>) +int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, long <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -1985,7 +1981,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -1996,12 +1992,10 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_execp</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2051,7 +2045,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values< <refsynopsisdiv> <synopsis> Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>, - Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + Datum * <parameter>values</parameter>, const bool * <parameter>nulls</parameter>, bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -2117,7 +2111,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> An array describing which parameters are null. Must have same length as @@ -2128,12 +2122,10 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> @@ -2177,7 +2169,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, const char *<parameter>command</parameter>, int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>, - Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>, + Datum *<parameter>values</parameter>, const bool *<parameter>nulls</parameter>, bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>) </synopsis> </refsynopsisdiv> @@ -2261,7 +2253,7 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, </varlistentry> <varlistentry> - <term><literal>const char * <parameter>nulls</parameter></literal></term> + <term><literal>const bool * <parameter>nulls</parameter></literal></term> <listitem> <para> an array of length <parameter>nargs</parameter>, describing which @@ -2272,12 +2264,10 @@ Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>, If <parameter>nulls</parameter> is <symbol>NULL</symbol> then <function>SPI_cursor_open_with_args</function> assumes that no parameters are null. Otherwise, each entry of the <parameter>nulls</parameter> - array should be <literal>' '</literal> if the corresponding parameter - value is non-null, or <literal>'n'</literal> if the corresponding parameter + array should be <literal>false</literal> if the corresponding parameter + value is non-null, or <literal>true</literal> if the corresponding parameter value is null. (In the latter case, the actual value in the - corresponding <parameter>values</parameter> entry doesn't matter.) Note - that <parameter>nulls</parameter> is not a text string, just an array: - it does not need a <literal>'\0'</literal> terminator. + corresponding <parameter>values</parameter> entry doesn't matter.) </para> </listitem> </varlistentry> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index e28d242922..631ab2167a 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -70,7 +70,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *caller_dest); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const bool *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); @@ -536,7 +536,7 @@ SPI_exec(const char *src, long tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -563,7 +563,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, /* Obsolete version of SPI_execute_plan */ int -SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, long tcount) +SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount) { return SPI_execute_plan(plan, Values, Nulls, false, tcount); } @@ -634,7 +634,7 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, */ int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount) { @@ -669,7 +669,7 @@ SPI_execute_snapshot(SPIPlanPtr plan, int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount) { int res; @@ -1339,7 +1339,7 @@ SPI_freetuptable(SPITupleTable *tuptable) */ Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only) { Portal portal; @@ -1368,7 +1368,7 @@ Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions) { Portal result; @@ -2636,7 +2636,7 @@ fail: */ static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls) + Datum *Values, const bool *Nulls) { ParamListInfo paramLI; @@ -2649,7 +2649,7 @@ _SPI_convert_params(int nargs, Oid *argtypes, ParamExternData *prm = ¶mLI->params[i]; prm->value = Values[i]; - prm->isnull = (Nulls && Nulls[i] == 'n'); + prm->isnull = Nulls && Nulls[i]; prm->pflags = PARAM_FLAG_CONST; prm->ptype = argtypes[i]; } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 6e3a41062f..793766570d 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -216,7 +216,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, bool detectNewRows, int expect_OK); static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + Datum *vals, bool *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, @@ -2191,7 +2191,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, Oid save_userid; int save_sec_context; Datum vals[RI_MAX_NUMKEYS * 2]; - char nulls[RI_MAX_NUMKEYS * 2]; + bool nulls[RI_MAX_NUMKEYS * 2]; /* * Use the query type code to determine whether the query is run against @@ -2314,7 +2314,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls) + Datum *vals, bool *nulls) { const int16 *attnums; bool isnull; @@ -2327,7 +2327,7 @@ ri_ExtractValues(Relation rel, TupleTableSlot *slot, for (int i = 0; i < riinfo->nkeys; i++) { vals[i] = slot_getattr(slot, attnums[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 8a1fbda572..3c8fa2c95d 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -531,7 +531,7 @@ static char * pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) { Datum args[1]; - char nulls[1]; + bool nulls[1]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -570,7 +570,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) * Get the pg_rewrite tuple for this rule */ args[0] = ObjectIdGetDatum(ruleoid); - nulls[0] = ' '; + nulls[0] = false; spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid); @@ -724,7 +724,7 @@ static char * pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) { Datum args[2]; - char nulls[2]; + bool nulls[2]; int spirc; HeapTuple ruletup; TupleDesc rulettc; @@ -765,8 +765,8 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ args[0] = ObjectIdGetDatum(viewoid); args[1] = DirectFunctionCall1(namein, CStringGetDatum(ViewSelectRuleName)); - nulls[0] = ' '; - nulls[1] = ' '; + nulls[0] = false; + nulls[1] = false; spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0); if (spirc != SPI_OK_SELECT) elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid); diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 9c70603434..8e4bd34ff7 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -94,7 +94,7 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, @@ -104,16 +104,16 @@ extern int SPI_execute_plan_with_receiver(SPIPlanPtr plan, bool read_only, long tcount, DestReceiver *dest); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const bool *Nulls, long tcount); extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount); extern int SPI_execute_with_args(const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, long tcount); extern int SPI_execute_with_receiver(const char *src, ParamListInfo params, @@ -161,11 +161,11 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const bool *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, const char *src, int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, + Datum *Values, const bool *Nulls, bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, ParamListInfo params, bool read_only); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 6299adf71a..1b8946d9fb 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -3806,7 +3806,7 @@ SV * plperl_spi_query_prepared(char *query, int argc, SV **argv) { int i; - char *nulls; + bool *nulls; Datum *argvalues; plperl_query_desc *qdesc; plperl_query_entry *hash_entry; @@ -3849,7 +3849,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); + nulls = (bool *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -3869,7 +3869,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) &qdesc->arginfuncs[i], qdesc->argtypioparams[i], &isnull); - nulls[i] = isnull ? 'n' : ' '; + nulls[i] = isnull; } /************************************************************ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 08d8b607e3..0918fe0f1f 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -201,11 +201,11 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) PG_TRY(); { Portal portal; - char *volatile nulls; + bool *volatile nulls; volatile int j; if (nargs > 0) - nulls = palloc(nargs * sizeof(char)); + nulls = palloc(nargs * sizeof(bool)); else nulls = NULL; @@ -220,7 +220,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args) bool isnull; plan->values[j] = PLy_output_convert(arg, elem, &isnull); - nulls[j] = isnull ? 'n' : ' '; + nulls[j] = isnull; } PG_FINALLY(); { diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 32ab9ed6b5..b31202d500 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -273,7 +273,7 @@ ttdummy(PG_FUNCTION_ARGS) Datum newon, newoff; Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ + bool *cnulls; /* column nulls */ char *relname; /* triggered relation name */ Relation rel; /* triggered relation */ HeapTuple trigtuple; @@ -374,27 +374,27 @@ ttdummy(PG_FUNCTION_ARGS) /* Fetch tuple values and nulls */ cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); + cnulls = (bool *) palloc(natts * sizeof(bool)); for (i = 0; i < natts; i++) { cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; + cnulls[i] = isnull; } /* change date column(s) */ if (newtuple) /* UPDATE */ { cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; + cnulls[attnum[0] - 1] = false; cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } else /* DELETE */ { cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; + cnulls[attnum[1] - 1] = false; } /* if there is no plan ... */ -- 2.30.0 --=-=-=-- ^ permalink raw reply [nested|flat] 24+ messages in thread
* Small cleanups to tuplesort.c and a bonus small performance improvement @ 2022-08-26 04:48 David Rowley <[email protected]> 2022-08-31 10:39 ` Re: Small cleanups to tuplesort.c and a bonus small performance improvement David Rowley <[email protected]> 0 siblings, 1 reply; 24+ messages in thread From: David Rowley @ 2022-08-26 04:48 UTC (permalink / raw) To: PostgreSQL Developers <[email protected]> Hi, Since doing some work for PG15 for speeding up sorts, I've been a little irritated by the fact that dumptuples() calls WRITETUP, (which is now always calling writetuple()) and calls pfree() on the tuple only for dumptuples() to do MemoryContextReset(state->base.tuplecontext) directly afterwards. These pfrees are just a waste of effort and we might as well leave it to the context reset to do the cleanup. (Probably especially so when using AllocSet for storing tuples) There are only 2 calls to WRITETUP and the other one is always called when state->slabAllocatorUsed is true. writetuple() checks for that before freeing the tuple, which is a bit of a wasted branch since it'll always prove to be false for the use case in mergeonerun(). (It's possible the compiler might inline that now anyway since the WRITETUP macro always calls writetuple() directly now) I've attached 3 patches aimed to do a small amount of cleanup work in tuplesort.c 0001: Just fixes a broken looking comment in writetuple() 0002: Gets rid of the WRITETUP marco. That does not do anything useful since 097366c45 0003: Changes writetuple to tell it what it should do in regards to freeing and adjusting the memory accounting. Probably 0003 could be done differently. I'm certainly not set on the bool args. I understand that I'm never calling it with "freetup" == true. So other options include 1) rip out the pfree code and that parameter; or 2) just do the inlining manually at both call sites. I'll throw this in the September CF to see if anyone wants to look. There's probably lots more cleaning jobs that could be done in tuplesort.c. The performance improvement from 0003 is not that impressive, but it looks like it makes things very slightly faster, so probably worth it if the patch makes the code cleaner. See attached gif and script for the benchmark I ran to test it. I think the gains might go up slightly with [1] applied as that patch seems to do more to improve the speed of palloc() than it does to improve the speed of pfree(). David [1] https://commitfest.postgresql.org/39/3810/ From 3a0dc2893c757be7cbde5d1cd1f7801de073f943 Mon Sep 17 00:00:00 2001 From: David Rowley <[email protected]> Date: Fri, 26 Aug 2022 14:42:23 +1200 Subject: [PATCH v1 3/3] Be smarter about freeing tuples during tuplesorts During dumptuples() the call to writetuple() would pfree any non-null tuple. This was quite wasteful as this happens just before we perform a reset of the context which stores all of those tuples. Here we adjust the writetuple signature so we can tell it exactly what we need done in regards to freeing the tuple and/or adjusting the memory accounting. In dumptuples() we must still account for the memory that's been released. Also, since writetuple() is only called twice, let's make it static inline so that the compiler inlines the call and removes the branching to check the bool arguments. --- src/backend/utils/sort/tuplesort.c | 44 ++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index d1c2f5f58f..519c7424f7 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -452,8 +452,9 @@ struct Sharedsort static void tuplesort_begin_batch(Tuplesortstate *state); -static void writetuple(Tuplesortstate *state, LogicalTape *tape, - SortTuple *stup); +static inline void writetuple(Tuplesortstate *state, LogicalTape *tape, + SortTuple *stup, bool freetup, + bool adjust_accounting); static bool consider_abort_common(Tuplesortstate *state); static void inittapes(Tuplesortstate *state, bool mergeruns); static void inittapestate(Tuplesortstate *state, int maxTapes); @@ -1339,18 +1340,22 @@ tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbre } /* - * Write 'stup' out onto 'tape' and, unless using the slab allocator, pfree - * stup's tuple and adjust the memory accounting accordingly. + * Write 'stup' out onto 'tape' and optionally free stup->tuple and optionally + * adjust the memory accounting. */ -static void -writetuple(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup) +static inline void +writetuple(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup, + bool freetup, bool adjust_accounting) { state->base.writetup(state, tape, stup); - if (!state->slabAllocatorUsed && stup->tuple) + if (stup->tuple != NULL) { - FREEMEM(state, GetMemoryChunkSpace(stup->tuple)); - pfree(stup->tuple); + if (adjust_accounting) + FREEMEM(state, GetMemoryChunkSpace(stup->tuple)); + + if (freetup) + pfree(stup->tuple); } } @@ -2251,6 +2256,8 @@ mergeonerun(Tuplesortstate *state) int srcTapeIndex; LogicalTape *srcTape; + Assert(state->slabAllocatorUsed); + /* * Start the merge by loading one tuple from each active source tape into * the heap. @@ -2269,7 +2276,7 @@ mergeonerun(Tuplesortstate *state) /* write the tuple to destTape */ srcTapeIndex = state->memtuples[0].srctape; srcTape = state->inputTapes[srcTapeIndex]; - writetuple(state, state->destTape, &state->memtuples[0]); + writetuple(state, state->destTape, &state->memtuples[0], false, false); /* recycle the slot of the tuple we just wrote out, for the next read */ if (state->memtuples[0].tuple) @@ -2415,16 +2422,23 @@ dumptuples(Tuplesortstate *state, bool alltuples) memtupwrite = state->memtupcount; for (i = 0; i < memtupwrite; i++) { - writetuple(state, state->destTape, &state->memtuples[i]); + /* + * No need to free the tuple as we're resetting the tuplecontext + * below. We do need to adjust the memory accounting for the tuple, + * however. + */ + writetuple(state, state->destTape, &state->memtuples[i], false, true); state->memtupcount--; } /* - * Reset tuple memory. We've freed all of the tuples that we previously - * allocated. It's important to avoid fragmentation when there is a stark - * change in the sizes of incoming tuples. Fragmentation due to + * Reset tuple memory. This saves us from having to pfree() each + * individual tuple and helps to avoid memory fragmentation when there is + * a stark change in the sizes of incoming tuples. Fragmentation due to * AllocSetFree's bucketing by size class might be particularly bad if - * this step wasn't taken. + * this step wasn't taken. We may be using the Generation allocator, + * which does not suffer from this issue, however it does not seem worth + * special handling for that. */ MemoryContextReset(state->base.tuplecontext); -- 2.34.1 From d4edd7a0011e8c9ded18bc85a326cb9540fe7d87 Mon Sep 17 00:00:00 2001 From: David Rowley <[email protected]> Date: Fri, 26 Aug 2022 14:06:15 +1200 Subject: [PATCH v1 2/3] Get rid of useless WRITETUP macro This always calls writetuple(), so there's no point in having it anymore. --- src/backend/utils/sort/tuplesort.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 4fe64f0793..d1c2f5f58f 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -395,7 +395,6 @@ struct Sharedsort #define REMOVEABBREV(state,stup,count) ((*(state)->base.removeabbrev) (state, stup, count)) #define COMPARETUP(state,a,b) ((*(state)->base.comparetup) (a, b, state)) -#define WRITETUP(state,tape,stup) (writetuple(state, tape, stup)) #define READTUP(state,stup,tape,len) ((*(state)->base.readtup) (state, stup, tape, len)) #define FREESTATE(state) ((state)->base.freestate ? (*(state)->base.freestate) (state) : (void) 0) #define LACKMEM(state) ((state)->availMem < 0 && !(state)->slabAllocatorUsed) @@ -2270,7 +2269,7 @@ mergeonerun(Tuplesortstate *state) /* write the tuple to destTape */ srcTapeIndex = state->memtuples[0].srctape; srcTape = state->inputTapes[srcTapeIndex]; - WRITETUP(state, state->destTape, &state->memtuples[0]); + writetuple(state, state->destTape, &state->memtuples[0]); /* recycle the slot of the tuple we just wrote out, for the next read */ if (state->memtuples[0].tuple) @@ -2416,7 +2415,7 @@ dumptuples(Tuplesortstate *state, bool alltuples) memtupwrite = state->memtupcount; for (i = 0; i < memtupwrite; i++) { - WRITETUP(state, state->destTape, &state->memtuples[i]); + writetuple(state, state->destTape, &state->memtuples[i]); state->memtupcount--; } -- 2.34.1 From 62fd0349f4550d3331843e8a7f7fe963fb90b8b6 Mon Sep 17 00:00:00 2001 From: David Rowley <[email protected]> Date: Fri, 26 Aug 2022 13:53:18 +1200 Subject: [PATCH v1 1/3] Improve wording in comment for writetuple function --- src/backend/utils/sort/tuplesort.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index d90a1aebdf..4fe64f0793 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -1340,10 +1340,8 @@ tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbre } /* - * Write a stored tuple onto tape.tuple. Unless the slab allocator is - * used, after writing the tuple, pfree() the out-of-line data (not the - * SortTuple struct!), and increase state->availMem by the amount of - * memory space thereby released. + * Write 'stup' out onto 'tape' and, unless using the slab allocator, pfree + * stup's tuple and adjust the memory accounting accordingly. */ static void writetuple(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup) -- 2.34.1 #!/bin/bash dbname=postgres times=5 gigabytes=10 psql -c "alter system set max_parallel_workers_per_gather TO 0;" $dbname psql -c "alter system set jit to 0;" $dbname psql -c "select pg_reload_conf();" $dbname #for cols in 6 7 8 9 10 11 12 13 14 for cols in 6 do sql="(" psql -c "drop table if exists t" $dbname psql -c "drop table if exists tsize" $dbname i=1 while [ $i -lt $cols ] do sql+="c$i BIGINT NOT NULL DEFAULT 0," i=$[$i+1] done sql+="c$cols BIGINT NOT NULL DEFAULT 0);" echo "NOTICE: Creating $cols column $gigabytes gigabyte table" # use the tsize table just to figure out how many of these rows we can fit on a page psql -c "create table tsize$sql" $dbname # 300 rows should always fill at least 1 page psql -c "insert into tsize (c1) select x from generate_series(1,300) x" $dbname psql -c "create table t$sql" $dbname # insert enough rows for $gigabytes gigabytes data psql -c "insert into t (c1) select x from generate_Series(1, (select count(*) * ($gigabytes::bigint*1024*1024*1024/8192) from tsize where ctid < '(1,0)')) x;" $dbname psql -c "vacuum freeze t" $dbname for mem in "4MB" "8MB" "16MB" "32MB" "64MB" "128MB" "256MB" "512MB" "1024MB" "2048MB" "4096MB" "8192MB" "16384MB" #for mem in "64MB" "65MB" do psql -c "alter system set work_mem TO '$mem';" $dbname psql -c "select pg_reload_conf();" $dbname echo "NOTICE: $cols column $gigabytes gigabyte table with work_mem of $mem" for sql in "select * from t order by c1 offset 1000000000000" do echo "$sql" > bench.sql pgbench -n -f bench.sql -t $times -M prepared $dbname done done done Attachments: [text/plain] v1-0003-Be-smarter-about-freeing-tuples-during-tuplesorts.patch (4.5K, ../../CAApHDvqZXoDCyrfCzZJR0-xH+7_q+GgitcQiYXUjRani7h4j8Q@mail.gmail.com/2-v1-0003-Be-smarter-about-freeing-tuples-during-tuplesorts.patch) download | inline diff: From 3a0dc2893c757be7cbde5d1cd1f7801de073f943 Mon Sep 17 00:00:00 2001 From: David Rowley <[email protected]> Date: Fri, 26 Aug 2022 14:42:23 +1200 Subject: [PATCH v1 3/3] Be smarter about freeing tuples during tuplesorts During dumptuples() the call to writetuple() would pfree any non-null tuple. This was quite wasteful as this happens just before we perform a reset of the context which stores all of those tuples. Here we adjust the writetuple signature so we can tell it exactly what we need done in regards to freeing the tuple and/or adjusting the memory accounting. In dumptuples() we must still account for the memory that's been released. Also, since writetuple() is only called twice, let's make it static inline so that the compiler inlines the call and removes the branching to check the bool arguments. --- src/backend/utils/sort/tuplesort.c | 44 ++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index d1c2f5f58f..519c7424f7 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -452,8 +452,9 @@ struct Sharedsort static void tuplesort_begin_batch(Tuplesortstate *state); -static void writetuple(Tuplesortstate *state, LogicalTape *tape, - SortTuple *stup); +static inline void writetuple(Tuplesortstate *state, LogicalTape *tape, + SortTuple *stup, bool freetup, + bool adjust_accounting); static bool consider_abort_common(Tuplesortstate *state); static void inittapes(Tuplesortstate *state, bool mergeruns); static void inittapestate(Tuplesortstate *state, int maxTapes); @@ -1339,18 +1340,22 @@ tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbre } /* - * Write 'stup' out onto 'tape' and, unless using the slab allocator, pfree - * stup's tuple and adjust the memory accounting accordingly. + * Write 'stup' out onto 'tape' and optionally free stup->tuple and optionally + * adjust the memory accounting. */ -static void -writetuple(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup) +static inline void +writetuple(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup, + bool freetup, bool adjust_accounting) { state->base.writetup(state, tape, stup); - if (!state->slabAllocatorUsed && stup->tuple) + if (stup->tuple != NULL) { - FREEMEM(state, GetMemoryChunkSpace(stup->tuple)); - pfree(stup->tuple); + if (adjust_accounting) + FREEMEM(state, GetMemoryChunkSpace(stup->tuple)); + + if (freetup) + pfree(stup->tuple); } } @@ -2251,6 +2256,8 @@ mergeonerun(Tuplesortstate *state) int srcTapeIndex; LogicalTape *srcTape; + Assert(state->slabAllocatorUsed); + /* * Start the merge by loading one tuple from each active source tape into * the heap. @@ -2269,7 +2276,7 @@ mergeonerun(Tuplesortstate *state) /* write the tuple to destTape */ srcTapeIndex = state->memtuples[0].srctape; srcTape = state->inputTapes[srcTapeIndex]; - writetuple(state, state->destTape, &state->memtuples[0]); + writetuple(state, state->destTape, &state->memtuples[0], false, false); /* recycle the slot of the tuple we just wrote out, for the next read */ if (state->memtuples[0].tuple) @@ -2415,16 +2422,23 @@ dumptuples(Tuplesortstate *state, bool alltuples) memtupwrite = state->memtupcount; for (i = 0; i < memtupwrite; i++) { - writetuple(state, state->destTape, &state->memtuples[i]); + /* + * No need to free the tuple as we're resetting the tuplecontext + * below. We do need to adjust the memory accounting for the tuple, + * however. + */ + writetuple(state, state->destTape, &state->memtuples[i], false, true); state->memtupcount--; } /* - * Reset tuple memory. We've freed all of the tuples that we previously - * allocated. It's important to avoid fragmentation when there is a stark - * change in the sizes of incoming tuples. Fragmentation due to + * Reset tuple memory. This saves us from having to pfree() each + * individual tuple and helps to avoid memory fragmentation when there is + * a stark change in the sizes of incoming tuples. Fragmentation due to * AllocSetFree's bucketing by size class might be particularly bad if - * this step wasn't taken. + * this step wasn't taken. We may be using the Generation allocator, + * which does not suffer from this issue, however it does not seem worth + * special handling for that. */ MemoryContextReset(state->base.tuplecontext); -- 2.34.1 [text/plain] v1-0002-Get-rid-of-useless-WRITETUP-macro.patch (1.8K, ../../CAApHDvqZXoDCyrfCzZJR0-xH+7_q+GgitcQiYXUjRani7h4j8Q@mail.gmail.com/3-v1-0002-Get-rid-of-useless-WRITETUP-macro.patch) download | inline diff: From d4edd7a0011e8c9ded18bc85a326cb9540fe7d87 Mon Sep 17 00:00:00 2001 From: David Rowley <[email protected]> Date: Fri, 26 Aug 2022 14:06:15 +1200 Subject: [PATCH v1 2/3] Get rid of useless WRITETUP macro This always calls writetuple(), so there's no point in having it anymore. --- src/backend/utils/sort/tuplesort.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 4fe64f0793..d1c2f5f58f 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -395,7 +395,6 @@ struct Sharedsort #define REMOVEABBREV(state,stup,count) ((*(state)->base.removeabbrev) (state, stup, count)) #define COMPARETUP(state,a,b) ((*(state)->base.comparetup) (a, b, state)) -#define WRITETUP(state,tape,stup) (writetuple(state, tape, stup)) #define READTUP(state,stup,tape,len) ((*(state)->base.readtup) (state, stup, tape, len)) #define FREESTATE(state) ((state)->base.freestate ? (*(state)->base.freestate) (state) : (void) 0) #define LACKMEM(state) ((state)->availMem < 0 && !(state)->slabAllocatorUsed) @@ -2270,7 +2269,7 @@ mergeonerun(Tuplesortstate *state) /* write the tuple to destTape */ srcTapeIndex = state->memtuples[0].srctape; srcTape = state->inputTapes[srcTapeIndex]; - WRITETUP(state, state->destTape, &state->memtuples[0]); + writetuple(state, state->destTape, &state->memtuples[0]); /* recycle the slot of the tuple we just wrote out, for the next read */ if (state->memtuples[0].tuple) @@ -2416,7 +2415,7 @@ dumptuples(Tuplesortstate *state, bool alltuples) memtupwrite = state->memtupcount; for (i = 0; i < memtupwrite; i++) { - WRITETUP(state, state->destTape, &state->memtuples[i]); + writetuple(state, state->destTape, &state->memtuples[i]); state->memtupcount--; } -- 2.34.1 [text/plain] v1-0001-Improve-wording-in-comment-for-writetuple-functio.patch (1.1K, ../../CAApHDvqZXoDCyrfCzZJR0-xH+7_q+GgitcQiYXUjRani7h4j8Q@mail.gmail.com/4-v1-0001-Improve-wording-in-comment-for-writetuple-functio.patch) download | inline diff: From 62fd0349f4550d3331843e8a7f7fe963fb90b8b6 Mon Sep 17 00:00:00 2001 From: David Rowley <[email protected]> Date: Fri, 26 Aug 2022 13:53:18 +1200 Subject: [PATCH v1 1/3] Improve wording in comment for writetuple function --- src/backend/utils/sort/tuplesort.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index d90a1aebdf..4fe64f0793 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -1340,10 +1340,8 @@ tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbre } /* - * Write a stored tuple onto tape.tuple. Unless the slab allocator is - * used, after writing the tuple, pfree() the out-of-line data (not the - * SortTuple struct!), and increase state->availMem by the amount of - * memory space thereby released. + * Write 'stup' out onto 'tape' and, unless using the slab allocator, pfree + * stup's tuple and adjust the memory accounting accordingly. */ static void writetuple(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup) -- 2.34.1 [image/gif] tuplesort_fixes.gif (47.7K, ../../CAApHDvqZXoDCyrfCzZJR0-xH+7_q+GgitcQiYXUjRani7h4j8Q@mail.gmail.com/5-tuplesort_fixes.gif) download | view image [text/plain] sortbench_varcols.sh.txt (1.6K, ../../CAApHDvqZXoDCyrfCzZJR0-xH+7_q+GgitcQiYXUjRani7h4j8Q@mail.gmail.com/6-sortbench_varcols.sh.txt) download | inline: #!/bin/bash dbname=postgres times=5 gigabytes=10 psql -c "alter system set max_parallel_workers_per_gather TO 0;" $dbname psql -c "alter system set jit to 0;" $dbname psql -c "select pg_reload_conf();" $dbname #for cols in 6 7 8 9 10 11 12 13 14 for cols in 6 do sql="(" psql -c "drop table if exists t" $dbname psql -c "drop table if exists tsize" $dbname i=1 while [ $i -lt $cols ] do sql+="c$i BIGINT NOT NULL DEFAULT 0," i=$[$i+1] done sql+="c$cols BIGINT NOT NULL DEFAULT 0);" echo "NOTICE: Creating $cols column $gigabytes gigabyte table" # use the tsize table just to figure out how many of these rows we can fit on a page psql -c "create table tsize$sql" $dbname # 300 rows should always fill at least 1 page psql -c "insert into tsize (c1) select x from generate_series(1,300) x" $dbname psql -c "create table t$sql" $dbname # insert enough rows for $gigabytes gigabytes data psql -c "insert into t (c1) select x from generate_Series(1, (select count(*) * ($gigabytes::bigint*1024*1024*1024/8192) from tsize where ctid < '(1,0)')) x;" $dbname psql -c "vacuum freeze t" $dbname for mem in "4MB" "8MB" "16MB" "32MB" "64MB" "128MB" "256MB" "512MB" "1024MB" "2048MB" "4096MB" "8192MB" "16384MB" #for mem in "64MB" "65MB" do psql -c "alter system set work_mem TO '$mem';" $dbname psql -c "select pg_reload_conf();" $dbname echo "NOTICE: $cols column $gigabytes gigabyte table with work_mem of $mem" for sql in "select * from t order by c1 offset 1000000000000" do echo "$sql" > bench.sql pgbench -n -f bench.sql -t $times -M prepared $dbname done done done ^ permalink raw reply [nested|flat] 24+ messages in thread
* Re: Small cleanups to tuplesort.c and a bonus small performance improvement 2022-08-26 04:48 Small cleanups to tuplesort.c and a bonus small performance improvement David Rowley <[email protected]> @ 2022-08-31 10:39 ` David Rowley <[email protected]> 2022-08-31 23:28 ` Re: Small cleanups to tuplesort.c and a bonus small performance improvement David Rowley <[email protected]> 0 siblings, 1 reply; 24+ messages in thread From: David Rowley @ 2022-08-31 10:39 UTC (permalink / raw) To: PostgreSQL Developers <[email protected]> On Fri, 26 Aug 2022 at 16:48, David Rowley <[email protected]> wrote: > 0003: Changes writetuple to tell it what it should do in regards to > freeing and adjusting the memory accounting. > > Probably 0003 could be done differently. I'm certainly not set on the > bool args. I understand that I'm never calling it with "freetup" == > true. So other options include 1) rip out the pfree code and that > parameter; or 2) just do the inlining manually at both call sites. This patch series needed to be rebased and on looking it at again, since the pfree() code is never used I felt it makes very little sense to keep it, so I decided that it might be better just to keep the WRITETUP macro and just completely get rid of the writetuple function and have the macro call the function pointed to be the "writetup" pointer. The only extra code we needed from writetuple() was the memory accounting code which was only used in dumptuples(), so I've just included that code in that function instead. I also noticed that dumptuples() had a pretty braindead method of zeroing out state->memtupcount by subtracting 1 from it on each loop. Since that's not being used to keep track of the loop's progress, I've just moved it out the loop and changed the code to set it to 0 once the loop is done. > I'll throw this in the September CF to see if anyone wants to look. > There's probably lots more cleaning jobs that could be done in > tuplesort.c. My current thoughts are that this is a very trivial patch and unless there's any objections I plan to push it soon. David From 7d9d960c6080f9511ecb2514defed386b9b65cdb Mon Sep 17 00:00:00 2001 From: David Rowley <[email protected]> Date: Wed, 31 Aug 2022 18:52:11 +1200 Subject: [PATCH v2] Be smarter about freeing tuples during tuplesorts During dumptuples() the call to writetuple() would pfree any non-null tuple. This was quite wasteful as this happens just before we perform a reset of the context which stores all of those tuples. It seems to make sense to do a bit of a code refactor to make this work, so here we just get rid of the writetuple function and adjust the WRITETUP macro to call the state's writetup function. The WRITETUP usage in mergeonerun() always has state->slabAllocatorUsed == true, so writetuple() would never free the tuple or do any memory accounting. The only call path that needs memory accounting done is in dumptuples(), so let's just do it manually there. In passing, let's get rid of the state->memtupcount-- code that counts the memtupcount down to 0 one tuple at a time inside the loop. That seems to be a rather inefficient way to set memtupcount to 0, so let's just zero it after the loop instead. --- src/backend/utils/sort/tuplesort.c | 38 ++++++++++++------------------ 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 66950983e6..416f02ba3c 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -395,7 +395,7 @@ struct Sharedsort #define REMOVEABBREV(state,stup,count) ((*(state)->base.removeabbrev) (state, stup, count)) #define COMPARETUP(state,a,b) ((*(state)->base.comparetup) (a, b, state)) -#define WRITETUP(state,tape,stup) (writetuple(state, tape, stup)) +#define WRITETUP(state,tape,stup) ((*(state)->base.writetup) (state, tape, stup)) #define READTUP(state,stup,tape,len) ((*(state)->base.readtup) (state, stup, tape, len)) #define FREESTATE(state) ((state)->base.freestate ? (*(state)->base.freestate) (state) : (void) 0) #define LACKMEM(state) ((state)->availMem < 0 && !(state)->slabAllocatorUsed) @@ -453,8 +453,6 @@ struct Sharedsort static void tuplesort_begin_batch(Tuplesortstate *state); -static void writetuple(Tuplesortstate *state, LogicalTape *tape, - SortTuple *stup); static bool consider_abort_common(Tuplesortstate *state); static void inittapes(Tuplesortstate *state, bool mergeruns); static void inittapestate(Tuplesortstate *state, int maxTapes); @@ -1339,24 +1337,6 @@ tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbre MemoryContextSwitchTo(oldcontext); } -/* - * Write a stored tuple onto tape. Unless the slab allocator is - * used, after writing the tuple, pfree() the out-of-line data (not the - * SortTuple struct!), and increase state->availMem by the amount of - * memory space thereby released. - */ -static void -writetuple(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup) -{ - state->base.writetup(state, tape, stup); - - if (!state->slabAllocatorUsed && stup->tuple) - { - FREEMEM(state, GetMemoryChunkSpace(stup->tuple)); - pfree(stup->tuple); - } -} - static bool consider_abort_common(Tuplesortstate *state) { @@ -2260,6 +2240,8 @@ mergeonerun(Tuplesortstate *state) */ beginmerge(state); + Assert(state->slabAllocatorUsed); + /* * Execute merge by repeatedly extracting lowest tuple in heap, writing it * out, and replacing it with next tuple from same tape (if there is @@ -2418,10 +2400,20 @@ dumptuples(Tuplesortstate *state, bool alltuples) memtupwrite = state->memtupcount; for (i = 0; i < memtupwrite; i++) { - WRITETUP(state, state->destTape, &state->memtuples[i]); - state->memtupcount--; + SortTuple *stup = &state->memtuples[i]; + + WRITETUP(state, state->destTape, stup); + + /* + * Account for freeing the tuple, but no need to do the actual pfree + * since the tuplecontext is being reset after the loop. + */ + if (stup->tuple != NULL) + FREEMEM(state, GetMemoryChunkSpace(stup->tuple)); } + state->memtupcount = 0; + /* * Reset tuple memory. We've freed all of the tuples that we previously * allocated. It's important to avoid fragmentation when there is a stark -- 2.34.1 Attachments: [text/plain] v2-0001-Be-smarter-about-freeing-tuples-during-tuplesorts.patch (4.1K, ../../CAApHDvrRLjEO3Vmpo79mDihNRMOVBZObOEi7Jy5b=o5QvcPiHw@mail.gmail.com/2-v2-0001-Be-smarter-about-freeing-tuples-during-tuplesorts.patch) download | inline diff: From 7d9d960c6080f9511ecb2514defed386b9b65cdb Mon Sep 17 00:00:00 2001 From: David Rowley <[email protected]> Date: Wed, 31 Aug 2022 18:52:11 +1200 Subject: [PATCH v2] Be smarter about freeing tuples during tuplesorts During dumptuples() the call to writetuple() would pfree any non-null tuple. This was quite wasteful as this happens just before we perform a reset of the context which stores all of those tuples. It seems to make sense to do a bit of a code refactor to make this work, so here we just get rid of the writetuple function and adjust the WRITETUP macro to call the state's writetup function. The WRITETUP usage in mergeonerun() always has state->slabAllocatorUsed == true, so writetuple() would never free the tuple or do any memory accounting. The only call path that needs memory accounting done is in dumptuples(), so let's just do it manually there. In passing, let's get rid of the state->memtupcount-- code that counts the memtupcount down to 0 one tuple at a time inside the loop. That seems to be a rather inefficient way to set memtupcount to 0, so let's just zero it after the loop instead. --- src/backend/utils/sort/tuplesort.c | 38 ++++++++++++------------------ 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 66950983e6..416f02ba3c 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -395,7 +395,7 @@ struct Sharedsort #define REMOVEABBREV(state,stup,count) ((*(state)->base.removeabbrev) (state, stup, count)) #define COMPARETUP(state,a,b) ((*(state)->base.comparetup) (a, b, state)) -#define WRITETUP(state,tape,stup) (writetuple(state, tape, stup)) +#define WRITETUP(state,tape,stup) ((*(state)->base.writetup) (state, tape, stup)) #define READTUP(state,stup,tape,len) ((*(state)->base.readtup) (state, stup, tape, len)) #define FREESTATE(state) ((state)->base.freestate ? (*(state)->base.freestate) (state) : (void) 0) #define LACKMEM(state) ((state)->availMem < 0 && !(state)->slabAllocatorUsed) @@ -453,8 +453,6 @@ struct Sharedsort static void tuplesort_begin_batch(Tuplesortstate *state); -static void writetuple(Tuplesortstate *state, LogicalTape *tape, - SortTuple *stup); static bool consider_abort_common(Tuplesortstate *state); static void inittapes(Tuplesortstate *state, bool mergeruns); static void inittapestate(Tuplesortstate *state, int maxTapes); @@ -1339,24 +1337,6 @@ tuplesort_puttuple_common(Tuplesortstate *state, SortTuple *tuple, bool useAbbre MemoryContextSwitchTo(oldcontext); } -/* - * Write a stored tuple onto tape. Unless the slab allocator is - * used, after writing the tuple, pfree() the out-of-line data (not the - * SortTuple struct!), and increase state->availMem by the amount of - * memory space thereby released. - */ -static void -writetuple(Tuplesortstate *state, LogicalTape *tape, SortTuple *stup) -{ - state->base.writetup(state, tape, stup); - - if (!state->slabAllocatorUsed && stup->tuple) - { - FREEMEM(state, GetMemoryChunkSpace(stup->tuple)); - pfree(stup->tuple); - } -} - static bool consider_abort_common(Tuplesortstate *state) { @@ -2260,6 +2240,8 @@ mergeonerun(Tuplesortstate *state) */ beginmerge(state); + Assert(state->slabAllocatorUsed); + /* * Execute merge by repeatedly extracting lowest tuple in heap, writing it * out, and replacing it with next tuple from same tape (if there is @@ -2418,10 +2400,20 @@ dumptuples(Tuplesortstate *state, bool alltuples) memtupwrite = state->memtupcount; for (i = 0; i < memtupwrite; i++) { - WRITETUP(state, state->destTape, &state->memtuples[i]); - state->memtupcount--; + SortTuple *stup = &state->memtuples[i]; + + WRITETUP(state, state->destTape, stup); + + /* + * Account for freeing the tuple, but no need to do the actual pfree + * since the tuplecontext is being reset after the loop. + */ + if (stup->tuple != NULL) + FREEMEM(state, GetMemoryChunkSpace(stup->tuple)); } + state->memtupcount = 0; + /* * Reset tuple memory. We've freed all of the tuples that we previously * allocated. It's important to avoid fragmentation when there is a stark -- 2.34.1 ^ permalink raw reply [nested|flat] 24+ messages in thread
* Re: Small cleanups to tuplesort.c and a bonus small performance improvement 2022-08-26 04:48 Small cleanups to tuplesort.c and a bonus small performance improvement David Rowley <[email protected]> 2022-08-31 10:39 ` Re: Small cleanups to tuplesort.c and a bonus small performance improvement David Rowley <[email protected]> @ 2022-08-31 23:28 ` David Rowley <[email protected]> 0 siblings, 0 replies; 24+ messages in thread From: David Rowley @ 2022-08-31 23:28 UTC (permalink / raw) To: PostgreSQL Developers <[email protected]> On Wed, 31 Aug 2022 at 22:39, David Rowley <[email protected]> wrote: > My current thoughts are that this is a very trivial patch and unless > there's any objections I plan to push it soon. Pushed. David ^ permalink raw reply [nested|flat] 24+ messages in thread
end of thread, other threads:[~2022-08-31 23:28 UTC | newest] Thread overview: 24+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2021-01-19 07:51 [PATCH v1] Replace the char to bool array for null parameters Japin Li <[email protected]> 2022-08-26 04:48 Small cleanups to tuplesort.c and a bonus small performance improvement David Rowley <[email protected]> 2022-08-31 10:39 ` Re: Small cleanups to tuplesort.c and a bonus small performance improvement David Rowley <[email protected]> 2022-08-31 23:28 ` Re: Small cleanups to tuplesort.c and a bonus small performance improvement David Rowley <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox