public inbox for [email protected]
help / color / mirror / Atom feedFrom: Japin Li <[email protected]>
Subject: [PATCH v1] Replace the char to bool array for null parameters
Date: Tue, 19 Jan 2021 15:51:44 +0800
---
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
--=-=-=--
view thread (25+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v1] Replace the char to bool array for null parameters
In-Reply-To: <no-message-id-1872378@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox