Add Boolean node
authorPeter Eisentraut <peter@eisentraut.org>
Fri, 14 Jan 2022 09:46:49 +0000 (10:46 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Mon, 17 Jan 2022 09:38:23 +0000 (10:38 +0100)
Before, SQL-level boolean constants were represented by a string with
a cast, and internal Boolean values in DDL commands were usually
represented by Integer nodes.  This takes the place of both of these
uses, making the intent clearer and having some amount of type safety.

Reviewed-by: Pavel Stehule <pavel.stehule@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/8c1a2e37-c68d-703c-5a83-7a6077f4f997@enterprisedb.com

20 files changed:
contrib/postgres_fdw/postgres_fdw.c
src/backend/commands/define.c
src/backend/commands/functioncmds.c
src/backend/commands/sequence.c
src/backend/commands/tsearchcmds.c
src/backend/commands/user.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/nodeFuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/read.c
src/backend/nodes/value.c
src/backend/parser/gram.y
src/backend/parser/parse_node.c
src/backend/replication/repl_gram.y
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/nodes/value.h
src/test/isolation/expected/ri-trigger.out
src/test/regress/expected/create_function_3.out

index 09a3f5e23cb6b832394e9ce8581be8f31b1964e7..bf3f3d9e26edebf6eeb0e8daf3a14c9f8e6b5df1 100644 (file)
@@ -103,7 +103,7 @@ enum FdwModifyPrivateIndex
    FdwModifyPrivateTargetAttnums,
    /* Length till the end of VALUES clause (as an Integer node) */
    FdwModifyPrivateLen,
-   /* has-returning flag (as an Integer node) */
+   /* has-returning flag (as a Boolean node) */
    FdwModifyPrivateHasReturning,
    /* Integer list of attribute numbers retrieved by RETURNING */
    FdwModifyPrivateRetrievedAttrs
@@ -122,11 +122,11 @@ enum FdwDirectModifyPrivateIndex
 {
    /* SQL statement to execute remotely (as a String node) */
    FdwDirectModifyPrivateUpdateSql,
-   /* has-returning flag (as an Integer node) */
+   /* has-returning flag (as a Boolean node) */
    FdwDirectModifyPrivateHasReturning,
    /* Integer list of attribute numbers retrieved by RETURNING */
    FdwDirectModifyPrivateRetrievedAttrs,
-   /* set-processed flag (as an Integer node) */
+   /* set-processed flag (as a Boolean node) */
    FdwDirectModifyPrivateSetProcessed
 };
 
@@ -280,9 +280,9 @@ typedef struct PgFdwAnalyzeState
  */
 enum FdwPathPrivateIndex
 {
-   /* has-final-sort flag (as an Integer node) */
+   /* has-final-sort flag (as a Boolean node) */
    FdwPathPrivateHasFinalSort,
-   /* has-limit flag (as an Integer node) */
+   /* has-limit flag (as a Boolean node) */
    FdwPathPrivateHasLimit
 };
 
@@ -1245,9 +1245,9 @@ postgresGetForeignPlan(PlannerInfo *root,
     */
    if (best_path->fdw_private)
    {
-       has_final_sort = intVal(list_nth(best_path->fdw_private,
+       has_final_sort = boolVal(list_nth(best_path->fdw_private,
                                         FdwPathPrivateHasFinalSort));
-       has_limit = intVal(list_nth(best_path->fdw_private,
+       has_limit = boolVal(list_nth(best_path->fdw_private,
                                    FdwPathPrivateHasLimit));
    }
 
@@ -1879,7 +1879,7 @@ postgresPlanForeignModify(PlannerInfo *root,
    return list_make5(makeString(sql.data),
                      targetAttrs,
                      makeInteger(values_end_len),
-                     makeInteger((retrieved_attrs != NIL)),
+                     makeBoolean((retrieved_attrs != NIL)),
                      retrieved_attrs);
 }
 
@@ -1916,7 +1916,7 @@ postgresBeginForeignModify(ModifyTableState *mtstate,
                                     FdwModifyPrivateTargetAttnums);
    values_end_len = intVal(list_nth(fdw_private,
                                     FdwModifyPrivateLen));
-   has_returning = intVal(list_nth(fdw_private,
+   has_returning = boolVal(list_nth(fdw_private,
                                    FdwModifyPrivateHasReturning));
    retrieved_attrs = (List *) list_nth(fdw_private,
                                        FdwModifyPrivateRetrievedAttrs);
@@ -2567,9 +2567,9 @@ postgresPlanDirectModify(PlannerInfo *root,
     * Items in the list must match enum FdwDirectModifyPrivateIndex, above.
     */
    fscan->fdw_private = list_make4(makeString(sql.data),
-                                   makeInteger((retrieved_attrs != NIL)),
+                                   makeBoolean((retrieved_attrs != NIL)),
                                    retrieved_attrs,
-                                   makeInteger(plan->canSetTag));
+                                   makeBoolean(plan->canSetTag));
 
    /*
     * Update the foreign-join-related fields.
@@ -2667,11 +2667,11 @@ postgresBeginDirectModify(ForeignScanState *node, int eflags)
    /* Get private info created by planner functions. */
    dmstate->query = strVal(list_nth(fsplan->fdw_private,
                                     FdwDirectModifyPrivateUpdateSql));
-   dmstate->has_returning = intVal(list_nth(fsplan->fdw_private,
+   dmstate->has_returning = boolVal(list_nth(fsplan->fdw_private,
                                             FdwDirectModifyPrivateHasReturning));
    dmstate->retrieved_attrs = (List *) list_nth(fsplan->fdw_private,
                                                 FdwDirectModifyPrivateRetrievedAttrs);
-   dmstate->set_processed = intVal(list_nth(fsplan->fdw_private,
+   dmstate->set_processed = boolVal(list_nth(fsplan->fdw_private,
                                             FdwDirectModifyPrivateSetProcessed));
 
    /* Create context for per-tuple temp workspace. */
@@ -6566,7 +6566,7 @@ add_foreign_ordered_paths(PlannerInfo *root, RelOptInfo *input_rel,
     * Build the fdw_private list that will be used by postgresGetForeignPlan.
     * Items in the list must match order in enum FdwPathPrivateIndex.
     */
-   fdw_private = list_make2(makeInteger(true), makeInteger(false));
+   fdw_private = list_make2(makeBoolean(true), makeBoolean(false));
 
    /* Create foreign ordering path */
    ordered_path = create_foreign_upper_path(root,
@@ -6797,8 +6797,8 @@ add_foreign_final_paths(PlannerInfo *root, RelOptInfo *input_rel,
     * Build the fdw_private list that will be used by postgresGetForeignPlan.
     * Items in the list must match order in enum FdwPathPrivateIndex.
     */
-   fdw_private = list_make2(makeInteger(has_final_sort),
-                            makeInteger(extra->limit_needed));
+   fdw_private = list_make2(makeBoolean(has_final_sort),
+                            makeBoolean(extra->limit_needed));
 
    /*
     * Create foreign final path; this gets rid of a no-longer-needed outer
index ce1a9df2688ac6b01d0340063d1216746a64fc1f..0755ab1eae539cb27a737a1617ae3282620de6e5 100644 (file)
@@ -59,6 +59,8 @@ defGetString(DefElem *def)
            return psprintf("%ld", (long) intVal(def->arg));
        case T_Float:
            return castNode(Float, def->arg)->fval;
+       case T_Boolean:
+           return boolVal(def->arg) ? "true" : "false";
        case T_String:
            return strVal(def->arg);
        case T_TypeName:
index 119b79598277c69e3005fc6cef40e88fecfede6c..25b75375a8e3cac1fac78142fc05029da58b23b4 100644 (file)
@@ -813,15 +813,15 @@ compute_function_attributes(ParseState *pstate,
    if (transform_item)
        *transform = transform_item->arg;
    if (windowfunc_item)
-       *windowfunc_p = intVal(windowfunc_item->arg);
+       *windowfunc_p = boolVal(windowfunc_item->arg);
    if (volatility_item)
        *volatility_p = interpret_func_volatility(volatility_item);
    if (strict_item)
-       *strict_p = intVal(strict_item->arg);
+       *strict_p = boolVal(strict_item->arg);
    if (security_item)
-       *security_definer = intVal(security_item->arg);
+       *security_definer = boolVal(security_item->arg);
    if (leakproof_item)
-       *leakproof_p = intVal(leakproof_item->arg);
+       *leakproof_p = boolVal(leakproof_item->arg);
    if (set_items)
        *proconfig = update_proconfig_value(NULL, set_items);
    if (cost_item)
@@ -1417,12 +1417,12 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)
    if (volatility_item)
        procForm->provolatile = interpret_func_volatility(volatility_item);
    if (strict_item)
-       procForm->proisstrict = intVal(strict_item->arg);
+       procForm->proisstrict = boolVal(strict_item->arg);
    if (security_def_item)
-       procForm->prosecdef = intVal(security_def_item->arg);
+       procForm->prosecdef = boolVal(security_def_item->arg);
    if (leakproof_item)
    {
-       procForm->proleakproof = intVal(leakproof_item->arg);
+       procForm->proleakproof = boolVal(leakproof_item->arg);
        if (procForm->proleakproof && !superuser())
            ereport(ERROR,
                    (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
index f2ffd42a05fff8f00ca673bf70a6d5c6d6a85ee2..27cb63075810e019a6a4c231880daf80eabc06ea 100644 (file)
@@ -1401,7 +1401,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
    /* CYCLE */
    if (is_cycled != NULL)
    {
-       seqform->seqcycle = intVal(is_cycled->arg);
+       seqform->seqcycle = boolVal(is_cycled->arg);
        Assert(BoolIsValid(seqform->seqcycle));
        seqdataform->log_cnt = 0;
    }
@@ -1739,7 +1739,7 @@ sequence_options(Oid relid)
    options = lappend(options,
                      makeDefElem("cache", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqcache)), -1));
    options = lappend(options,
-                     makeDefElem("cycle", (Node *) makeInteger(pgsform->seqcycle), -1));
+                     makeDefElem("cycle", (Node *) makeBoolean(pgsform->seqcycle), -1));
    options = lappend(options,
                      makeDefElem("increment", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqincrement)), -1));
    options = lappend(options,
index 39f0bf7a0d48e49a78f18a1b0095a4cdab4c3d0d..4cc4e3c00f8e239b96ac7c98d04e6b29a1d65005 100644 (file)
@@ -1742,6 +1742,15 @@ buildDefItem(const char *name, const char *val, bool was_quoted)
            return makeDefElem(pstrdup(name),
                               (Node *) makeFloat(pstrdup(val)),
                               -1);
+
+       if (strcmp(val, "true") == 0)
+           return makeDefElem(pstrdup(name),
+                              (Node *) makeBoolean(true),
+                              -1);
+       if (strcmp(val, "false") == 0)
+           return makeDefElem(pstrdup(name),
+                              (Node *) makeBoolean(false),
+                              -1);
    }
    /* Just make it a string */
    return makeDefElem(pstrdup(name),
index 5f6e94949b1934a5475cdd18dced253be49575aa..f9d3c1246bb2be6e7ca06442492994a0f86d82b0 100644 (file)
@@ -217,17 +217,17 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
    if (dpassword && dpassword->arg)
        password = strVal(dpassword->arg);
    if (dissuper)
-       issuper = intVal(dissuper->arg) != 0;
+       issuper = boolVal(dissuper->arg);
    if (dinherit)
-       inherit = intVal(dinherit->arg) != 0;
+       inherit = boolVal(dinherit->arg);
    if (dcreaterole)
-       createrole = intVal(dcreaterole->arg) != 0;
+       createrole = boolVal(dcreaterole->arg);
    if (dcreatedb)
-       createdb = intVal(dcreatedb->arg) != 0;
+       createdb = boolVal(dcreatedb->arg);
    if (dcanlogin)
-       canlogin = intVal(dcanlogin->arg) != 0;
+       canlogin = boolVal(dcanlogin->arg);
    if (disreplication)
-       isreplication = intVal(disreplication->arg) != 0;
+       isreplication = boolVal(disreplication->arg);
    if (dconnlimit)
    {
        connlimit = intVal(dconnlimit->arg);
@@ -245,7 +245,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
    if (dvalidUntil)
        validUntil = strVal(dvalidUntil->arg);
    if (dbypassRLS)
-       bypassrls = intVal(dbypassRLS->arg) != 0;
+       bypassrls = boolVal(dbypassRLS->arg);
 
    /* Check some permissions first */
    if (issuper)
@@ -700,37 +700,37 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
     */
    if (dissuper)
    {
-       new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(intVal(dissuper->arg));
+       new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(boolVal(dissuper->arg));
        new_record_repl[Anum_pg_authid_rolsuper - 1] = true;
    }
 
    if (dinherit)
    {
-       new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(intVal(dinherit->arg));
+       new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(boolVal(dinherit->arg));
        new_record_repl[Anum_pg_authid_rolinherit - 1] = true;
    }
 
    if (dcreaterole)
    {
-       new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(intVal(dcreaterole->arg));
+       new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(boolVal(dcreaterole->arg));
        new_record_repl[Anum_pg_authid_rolcreaterole - 1] = true;
    }
 
    if (dcreatedb)
    {
-       new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(intVal(dcreatedb->arg));
+       new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(boolVal(dcreatedb->arg));
        new_record_repl[Anum_pg_authid_rolcreatedb - 1] = true;
    }
 
    if (dcanlogin)
    {
-       new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(intVal(dcanlogin->arg));
+       new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(boolVal(dcanlogin->arg));
        new_record_repl[Anum_pg_authid_rolcanlogin - 1] = true;
    }
 
    if (disreplication)
    {
-       new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(intVal(disreplication->arg));
+       new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(boolVal(disreplication->arg));
        new_record_repl[Anum_pg_authid_rolreplication - 1] = true;
    }
 
@@ -779,7 +779,7 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
 
    if (dbypassRLS)
    {
-       new_record[Anum_pg_authid_rolbypassrls - 1] = BoolGetDatum(intVal(dbypassRLS->arg));
+       new_record[Anum_pg_authid_rolbypassrls - 1] = BoolGetDatum(boolVal(dbypassRLS->arg));
        new_record_repl[Anum_pg_authid_rolbypassrls - 1] = true;
    }
 
index b105c263810792d1a13c7619355f53f1e484201f..90b5da51c950a8b87920aaa9a1f86a66fe06d27f 100644 (file)
@@ -2750,6 +2750,9 @@ _copyA_Const(const A_Const *from)
            case T_Float:
                COPY_STRING_FIELD(val.fval.fval);
                break;
+           case T_Boolean:
+               COPY_SCALAR_FIELD(val.boolval.boolval);
+               break;
            case T_String:
                COPY_STRING_FIELD(val.sval.sval);
                break;
@@ -4949,6 +4952,16 @@ _copyFloat(const Float *from)
    return newnode;
 }
 
+static Boolean *
+_copyBoolean(const Boolean *from)
+{
+   Boolean    *newnode = makeNode(Boolean);
+
+   COPY_SCALAR_FIELD(boolval);
+
+   return newnode;
+}
+
 static String *
 _copyString(const String *from)
 {
@@ -5356,6 +5369,9 @@ copyObjectImpl(const void *from)
        case T_Float:
            retval = _copyFloat(from);
            break;
+       case T_Boolean:
+           retval = _copyBoolean(from);
+           break;
        case T_String:
            retval = _copyString(from);
            break;
index ae37ea9464b15d15ce02e4b8c3e63d9447977235..06345da3ba846b37b125965e3405c900625430cc 100644 (file)
@@ -3138,6 +3138,14 @@ _equalFloat(const Float *a, const Float *b)
    return true;
 }
 
+static bool
+_equalBoolean(const Boolean *a, const Boolean *b)
+{
+   COMPARE_SCALAR_FIELD(boolval);
+
+   return true;
+}
+
 static bool
 _equalString(const String *a, const String *b)
 {
@@ -3374,6 +3382,9 @@ equal(const void *a, const void *b)
        case T_Float:
            retval = _equalFloat(a, b);
            break;
+       case T_Boolean:
+           retval = _equalBoolean(a, b);
+           break;
        case T_String:
            retval = _equalString(a, b);
            break;
index acc17da7177b80b6612dd13c6168837a2f4b131d..47d0564fa29702a2dfa307e95b3cfdb0279f0d6b 100644 (file)
@@ -3577,6 +3577,7 @@ raw_expression_tree_walker(Node *node,
        case T_SQLValueFunction:
        case T_Integer:
        case T_Float:
+       case T_Boolean:
        case T_String:
        case T_BitString:
        case T_ParamRef:
index d28cea156703a862298834142071eff827cb49e4..2b0236937aafb28f97797c25e6e16b3fc60c864e 100644 (file)
@@ -3434,6 +3434,12 @@ _outFloat(StringInfo str, const Float *node)
    appendStringInfoString(str, node->fval);
 }
 
+static void
+_outBoolean(StringInfo str, const Boolean *node)
+{
+   appendStringInfoString(str, node->boolval ? "true" : "false");
+}
+
 static void
 _outString(StringInfo str, const String *node)
 {
@@ -3846,6 +3852,8 @@ outNode(StringInfo str, const void *obj)
        _outInteger(str, (Integer *) obj);
    else if (IsA(obj, Float))
        _outFloat(str, (Float *) obj);
+   else if (IsA(obj, Boolean))
+       _outBoolean(str, (Boolean *) obj);
    else if (IsA(obj, String))
        _outString(str, (String *) obj);
    else if (IsA(obj, BitString))
index 0460aad6ea5c7cb9d01d7d24a57bdbd886ca41d6..8435203f2bd1dc811e224e8a6af51bfa38ef1899 100644 (file)
@@ -235,7 +235,7 @@ debackslash(const char *token, int length)
  * nodeTokenType -
  *   returns the type of the node token contained in token.
  *   It returns one of the following valid NodeTags:
- *     T_Integer, T_Float, T_String, T_BitString
+ *     T_Integer, T_Float, T_Boolean, T_String, T_BitString
  *   and some of its own:
  *     RIGHT_PAREN, LEFT_PAREN, LEFT_BRACE, OTHER_TOKEN
  *
@@ -283,6 +283,8 @@ nodeTokenType(const char *token, int length)
        retval = RIGHT_PAREN;
    else if (*token == '{')
        retval = LEFT_BRACE;
+   else if (strcmp(token, "true") == 0 || strcmp(token, "false") == 0)
+       retval = T_Boolean;
    else if (*token == '"' && length > 1 && token[length - 1] == '"')
        retval = T_String;
    else if (*token == 'b')
@@ -298,7 +300,7 @@ nodeTokenType(const char *token, int length)
  *
  * This routine applies some semantic knowledge on top of the purely
  * lexical tokenizer pg_strtok().   It can read
- * * Value token nodes (integers, floats, or strings);
+ * * Value token nodes (integers, floats, booleans, or strings);
  * * General nodes (via parseNodeString() from readfuncs.c);
  * * Lists of the above;
  * * Lists of integers or OIDs.
@@ -438,6 +440,9 @@ nodeRead(const char *token, int tok_len)
                result = (Node *) makeFloat(fval);
            }
            break;
+       case T_Boolean:
+           result = (Node *) makeBoolean(token[0] == 't');
+           break;
        case T_String:
            /* need to remove leading and trailing quotes, and backslashes */
            result = (Node *) makeString(debackslash(token + 1, tok_len - 2));
index 6905cae6d319c4018b7afb2ca1dea2020b0a0651..6fe55f5dd5cbad9a5d5c38a9bd8ad3ee587ee7db 100644 (file)
@@ -42,6 +42,18 @@ makeFloat(char *numericStr)
    return v;
 }
 
+/*
+ * makeBoolean
+ */
+Boolean *
+makeBoolean(bool val)
+{
+   Boolean    *v = makeNode(Boolean);
+
+   v->boolval = val;
+   return v;
+}
+
 /*
  * makeString
  *
index bb015a8bbd3c74409febdc50a10109f4f4119cb7..b5966712ce140bacd546c767035553e9cd56e5d2 100644 (file)
@@ -177,10 +177,10 @@ static Node *makeStringConst(char *str, int location);
 static Node *makeStringConstCast(char *str, int location, TypeName *typename);
 static Node *makeIntConst(int val, int location);
 static Node *makeFloatConst(char *str, int location);
+static Node *makeBoolAConst(bool state, int location);
 static Node *makeBitStringConst(char *str, int location);
 static Node *makeNullAConst(int location);
 static Node *makeAConst(Node *v, int location);
-static Node *makeBoolAConst(bool state, int location);
 static RoleSpec *makeRoleSpec(RoleSpecType type, int location);
 static void check_qualified_name(List *names, core_yyscan_t yyscanner);
 static List *check_func_name(List *names, core_yyscan_t yyscanner);
@@ -1133,7 +1133,7 @@ AlterOptRoleElem:
                }
            | INHERIT
                {
-                   $$ = makeDefElem("inherit", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("inherit", (Node *)makeBoolean(true), @1);
                }
            | CONNECTION LIMIT SignedIconst
                {
@@ -1156,36 +1156,36 @@ AlterOptRoleElem:
                     * size of the main parser.
                     */
                    if (strcmp($1, "superuser") == 0)
-                       $$ = makeDefElem("superuser", (Node *)makeInteger(true), @1);
+                       $$ = makeDefElem("superuser", (Node *)makeBoolean(true), @1);
                    else if (strcmp($1, "nosuperuser") == 0)
-                       $$ = makeDefElem("superuser", (Node *)makeInteger(false), @1);
+                       $$ = makeDefElem("superuser", (Node *)makeBoolean(false), @1);
                    else if (strcmp($1, "createrole") == 0)
-                       $$ = makeDefElem("createrole", (Node *)makeInteger(true), @1);
+                       $$ = makeDefElem("createrole", (Node *)makeBoolean(true), @1);
                    else if (strcmp($1, "nocreaterole") == 0)
-                       $$ = makeDefElem("createrole", (Node *)makeInteger(false), @1);
+                       $$ = makeDefElem("createrole", (Node *)makeBoolean(false), @1);
                    else if (strcmp($1, "replication") == 0)
-                       $$ = makeDefElem("isreplication", (Node *)makeInteger(true), @1);
+                       $$ = makeDefElem("isreplication", (Node *)makeBoolean(true), @1);
                    else if (strcmp($1, "noreplication") == 0)
-                       $$ = makeDefElem("isreplication", (Node *)makeInteger(false), @1);
+                       $$ = makeDefElem("isreplication", (Node *)makeBoolean(false), @1);
                    else if (strcmp($1, "createdb") == 0)
-                       $$ = makeDefElem("createdb", (Node *)makeInteger(true), @1);
+                       $$ = makeDefElem("createdb", (Node *)makeBoolean(true), @1);
                    else if (strcmp($1, "nocreatedb") == 0)
-                       $$ = makeDefElem("createdb", (Node *)makeInteger(false), @1);
+                       $$ = makeDefElem("createdb", (Node *)makeBoolean(false), @1);
                    else if (strcmp($1, "login") == 0)
-                       $$ = makeDefElem("canlogin", (Node *)makeInteger(true), @1);
+                       $$ = makeDefElem("canlogin", (Node *)makeBoolean(true), @1);
                    else if (strcmp($1, "nologin") == 0)
-                       $$ = makeDefElem("canlogin", (Node *)makeInteger(false), @1);
+                       $$ = makeDefElem("canlogin", (Node *)makeBoolean(false), @1);
                    else if (strcmp($1, "bypassrls") == 0)
-                       $$ = makeDefElem("bypassrls", (Node *)makeInteger(true), @1);
+                       $$ = makeDefElem("bypassrls", (Node *)makeBoolean(true), @1);
                    else if (strcmp($1, "nobypassrls") == 0)
-                       $$ = makeDefElem("bypassrls", (Node *)makeInteger(false), @1);
+                       $$ = makeDefElem("bypassrls", (Node *)makeBoolean(false), @1);
                    else if (strcmp($1, "noinherit") == 0)
                    {
                        /*
                         * Note that INHERIT is a keyword, so it's handled by main parser, but
                         * NOINHERIT is handled here.
                         */
-                       $$ = makeDefElem("inherit", (Node *)makeInteger(false), @1);
+                       $$ = makeDefElem("inherit", (Node *)makeBoolean(false), @1);
                    }
                    else
                        ereport(ERROR,
@@ -3175,7 +3175,7 @@ copy_opt_item:
                }
            | FREEZE
                {
-                   $$ = makeDefElem("freeze", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("freeze", (Node *)makeBoolean(true), @1);
                }
            | DELIMITER opt_as Sconst
                {
@@ -3191,7 +3191,7 @@ copy_opt_item:
                }
            | HEADER_P
                {
-                   $$ = makeDefElem("header", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("header", (Node *)makeBoolean(true), @1);
                }
            | QUOTE opt_as Sconst
                {
@@ -4499,11 +4499,11 @@ SeqOptElem: AS SimpleTypename
                }
            | CYCLE
                {
-                   $$ = makeDefElem("cycle", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("cycle", (Node *)makeBoolean(true), @1);
                }
            | NO CYCLE
                {
-                   $$ = makeDefElem("cycle", (Node *)makeInteger(false), @1);
+                   $$ = makeDefElem("cycle", (Node *)makeBoolean(false), @1);
                }
            | INCREMENT opt_by NumericOnly
                {
@@ -4739,7 +4739,7 @@ create_extension_opt_item:
                }
            | CASCADE
                {
-                   $$ = makeDefElem("cascade", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("cascade", (Node *)makeBoolean(true), @1);
                }
        ;
 
@@ -7934,15 +7934,15 @@ createfunc_opt_list:
 common_func_opt_item:
            CALLED ON NULL_P INPUT_P
                {
-                   $$ = makeDefElem("strict", (Node *)makeInteger(false), @1);
+                   $$ = makeDefElem("strict", (Node *)makeBoolean(false), @1);
                }
            | RETURNS NULL_P ON NULL_P INPUT_P
                {
-                   $$ = makeDefElem("strict", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("strict", (Node *)makeBoolean(true), @1);
                }
            | STRICT_P
                {
-                   $$ = makeDefElem("strict", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("strict", (Node *)makeBoolean(true), @1);
                }
            | IMMUTABLE
                {
@@ -7958,27 +7958,27 @@ common_func_opt_item:
                }
            | EXTERNAL SECURITY DEFINER
                {
-                   $$ = makeDefElem("security", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("security", (Node *)makeBoolean(true), @1);
                }
            | EXTERNAL SECURITY INVOKER
                {
-                   $$ = makeDefElem("security", (Node *)makeInteger(false), @1);
+                   $$ = makeDefElem("security", (Node *)makeBoolean(false), @1);
                }
            | SECURITY DEFINER
                {
-                   $$ = makeDefElem("security", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("security", (Node *)makeBoolean(true), @1);
                }
            | SECURITY INVOKER
                {
-                   $$ = makeDefElem("security", (Node *)makeInteger(false), @1);
+                   $$ = makeDefElem("security", (Node *)makeBoolean(false), @1);
                }
            | LEAKPROOF
                {
-                   $$ = makeDefElem("leakproof", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("leakproof", (Node *)makeBoolean(true), @1);
                }
            | NOT LEAKPROOF
                {
-                   $$ = makeDefElem("leakproof", (Node *)makeInteger(false), @1);
+                   $$ = makeDefElem("leakproof", (Node *)makeBoolean(false), @1);
                }
            | COST NumericOnly
                {
@@ -8018,7 +8018,7 @@ createfunc_opt_item:
                }
            | WINDOW
                {
-                   $$ = makeDefElem("window", (Node *)makeInteger(true), @1);
+                   $$ = makeDefElem("window", (Node *)makeBoolean(true), @1);
                }
            | common_func_opt_item
                {
@@ -9941,7 +9941,7 @@ AlterSubscriptionStmt:
                    n->kind = ALTER_SUBSCRIPTION_ENABLED;
                    n->subname = $3;
                    n->options = list_make1(makeDefElem("enabled",
-                                           (Node *)makeInteger(true), @1));
+                                           (Node *)makeBoolean(true), @1));
                    $$ = (Node *)n;
                }
            | ALTER SUBSCRIPTION name DISABLE_P
@@ -9951,7 +9951,7 @@ AlterSubscriptionStmt:
                    n->kind = ALTER_SUBSCRIPTION_ENABLED;
                    n->subname = $3;
                    n->options = list_make1(makeDefElem("enabled",
-                                           (Node *)makeInteger(false), @1));
+                                           (Node *)makeBoolean(false), @1));
                    $$ = (Node *)n;
                }
        ;
@@ -12874,7 +12874,7 @@ xmltable_column_el:
                                        (errcode(ERRCODE_SYNTAX_ERROR),
                                         errmsg("conflicting or redundant NULL / NOT NULL declarations for column \"%s\"", fc->colname),
                                         parser_errposition(defel->location)));
-                           fc->is_not_null = intVal(defel->arg);
+                           fc->is_not_null = boolVal(defel->arg);
                            nullability_seen = true;
                        }
                        else
@@ -12914,9 +12914,9 @@ xmltable_column_option_el:
            | DEFAULT b_expr
                { $$ = makeDefElem("default", $2, @1); }
            | NOT NULL_P
-               { $$ = makeDefElem("is_not_null", (Node *) makeInteger(true), @1); }
+               { $$ = makeDefElem("is_not_null", (Node *) makeBoolean(true), @1); }
            | NULL_P
-               { $$ = makeDefElem("is_not_null", (Node *) makeInteger(false), @1); }
+               { $$ = makeDefElem("is_not_null", (Node *) makeBoolean(false), @1); }
        ;
 
 xml_namespace_list:
@@ -16705,6 +16705,18 @@ makeFloatConst(char *str, int location)
    return (Node *)n;
 }
 
+static Node *
+makeBoolAConst(bool state, int location)
+{
+   A_Const *n = makeNode(A_Const);
+
+   n->val.boolval.type = T_Boolean;
+   n->val.boolval.boolval = state;
+   n->location = location;
+
+   return (Node *)n;
+}
+
 static Node *
 makeBitStringConst(char *str, int location)
 {
@@ -16743,26 +16755,15 @@ makeAConst(Node *v, int location)
            n = makeIntConst(castNode(Integer, v)->ival, location);
            break;
 
-       case T_String:
        default:
-           n = makeStringConst(castNode(String, v)->sval, location);
-           break;
+           /* currently not used */
+           Assert(false);
+           n = NULL;
    }
 
    return n;
 }
 
-/* makeBoolAConst()
- * Create an A_Const string node and put it inside a boolean cast.
- */
-static Node *
-makeBoolAConst(bool state, int location)
-{
-   return makeStringConstCast((state ? "t" : "f"),
-                              location,
-                              SystemTypeName("bool"));
-}
-
 /* makeRoleSpec
  * Create a RoleSpec with the given type
  */
index 95913c8021582065d78b5ef764dd19f27579a9b5..35db6b6c988e1b1f7b9dc6b8da7e809ceac58faa 100644 (file)
@@ -426,6 +426,14 @@ make_const(ParseState *pstate, A_Const *aconst)
            }
            break;
 
+       case T_Boolean:
+           val = BoolGetDatum(boolVal(&aconst->val));
+
+           typeid = BOOLOID;
+           typelen = 1;
+           typebyval = true;
+           break;
+
        case T_String:
 
            /*
index 8800d10d5fe2663e27f767fdb69cdee4a4e129d3..6d1dbd72e911a898248ea0a78aec31f871724c87 100644 (file)
@@ -212,7 +212,7 @@ base_backup_legacy_opt:
            | K_PROGRESS
                {
                  $$ = makeDefElem("progress",
-                                  (Node *)makeInteger(true), -1);
+                                  (Node *)makeBoolean(true), -1);
                }
            | K_FAST
                {
@@ -222,12 +222,12 @@ base_backup_legacy_opt:
            | K_WAL
                {
                  $$ = makeDefElem("wal",
-                                  (Node *)makeInteger(true), -1);
+                                  (Node *)makeBoolean(true), -1);
                }
            | K_NOWAIT
                {
                  $$ = makeDefElem("wait",
-                                  (Node *)makeInteger(false), -1);
+                                  (Node *)makeBoolean(false), -1);
                }
            | K_MAX_RATE UCONST
                {
@@ -237,12 +237,12 @@ base_backup_legacy_opt:
            | K_TABLESPACE_MAP
                {
                  $$ = makeDefElem("tablespace_map",
-                                  (Node *)makeInteger(true), -1);
+                                  (Node *)makeBoolean(true), -1);
                }
            | K_NOVERIFY_CHECKSUMS
                {
                  $$ = makeDefElem("verify_checksums",
-                                  (Node *)makeInteger(false), -1);
+                                  (Node *)makeBoolean(false), -1);
                }
            | K_MANIFEST SCONST
                {
@@ -313,12 +313,12 @@ create_slot_legacy_opt:
            | K_RESERVE_WAL
                {
                  $$ = makeDefElem("reserve_wal",
-                                  (Node *)makeInteger(true), -1);
+                                  (Node *)makeBoolean(true), -1);
                }
            | K_TWO_PHASE
                {
                  $$ = makeDefElem("two_phase",
-                                  (Node *)makeInteger(true), -1);
+                                  (Node *)makeBoolean(true), -1);
                }
            ;
 
index 28cf5aefcae9cb478f04f803949ec8db387688d9..f9ddafd3459458bafcc9e767e2c9c7c2f537e53e 100644 (file)
@@ -292,6 +292,7 @@ typedef enum NodeTag
     */
    T_Integer,
    T_Float,
+   T_Boolean,
    T_String,
    T_BitString,
 
index 413e7c85a1ed56d78d39a5db583faa9637b80fcf..3e9bdc781f9bb5a447e4f4b0eacb9f23cf550f18 100644 (file)
@@ -304,6 +304,7 @@ typedef struct A_Const
        Node        node;
        Integer     ival;
        Float       fval;
+       Boolean     boolval;
        String      sval;
        BitString   bsval;
    }           val;
index 442cc19fcbaa46c8230e2092cc601d63859853b1..eaf937051c3bdcbbe299997a21ad349bf6013c98 100644 (file)
@@ -48,6 +48,12 @@ typedef struct Float
    char       *fval;
 } Float;
 
+typedef struct Boolean
+{
+   NodeTag     type;
+   bool        boolval;
+} Boolean;
+
 typedef struct String
 {
    NodeTag     type;
@@ -62,10 +68,12 @@ typedef struct BitString
 
 #define intVal(v)      (castNode(Integer, v)->ival)
 #define floatVal(v)        atof(castNode(Float, v)->fval)
+#define boolVal(v)     (castNode(Boolean, v)->boolval)
 #define strVal(v)      (castNode(String, v)->sval)
 
 extern Integer *makeInteger(int i);
 extern Float *makeFloat(char *numericStr);
+extern Boolean *makeBoolean(bool var);
 extern String *makeString(char *str);
 extern BitString *makeBitString(char *str);
 
index 842df80a90b0422f7fe906d103f922eedfa4f63f..db85618bef72b73910415b3984a67db8a8c64757 100644 (file)
@@ -4,9 +4,9 @@ starting permutation: wxry1 c1 r2 wyrx2 c2
 step wxry1: INSERT INTO child (parent_id) VALUES (0);
 step c1: COMMIT;
 step r2: SELECT TRUE;
-bool
-----
-t   
+?column?
+--------
+t       
 (1 row)
 
 step wyrx2: DELETE FROM parent WHERE parent_id = 0;
@@ -16,9 +16,9 @@ step c2: COMMIT;
 starting permutation: wxry1 r2 c1 wyrx2 c2
 step wxry1: INSERT INTO child (parent_id) VALUES (0);
 step r2: SELECT TRUE;
-bool
-----
-t   
+?column?
+--------
+t       
 (1 row)
 
 step c1: COMMIT;
@@ -29,9 +29,9 @@ step c2: COMMIT;
 starting permutation: wxry1 r2 wyrx2 c1 c2
 step wxry1: INSERT INTO child (parent_id) VALUES (0);
 step r2: SELECT TRUE;
-bool
-----
-t   
+?column?
+--------
+t       
 (1 row)
 
 step wyrx2: DELETE FROM parent WHERE parent_id = 0;
@@ -42,9 +42,9 @@ ERROR:  could not serialize access due to read/write dependencies among transact
 starting permutation: wxry1 r2 wyrx2 c2 c1
 step wxry1: INSERT INTO child (parent_id) VALUES (0);
 step r2: SELECT TRUE;
-bool
-----
-t   
+?column?
+--------
+t       
 (1 row)
 
 step wyrx2: DELETE FROM parent WHERE parent_id = 0;
@@ -54,9 +54,9 @@ ERROR:  could not serialize access due to read/write dependencies among transact
 
 starting permutation: r2 wxry1 c1 wyrx2 c2
 step r2: SELECT TRUE;
-bool
-----
-t   
+?column?
+--------
+t       
 (1 row)
 
 step wxry1: INSERT INTO child (parent_id) VALUES (0);
@@ -67,9 +67,9 @@ step c2: COMMIT;
 
 starting permutation: r2 wxry1 wyrx2 c1 c2
 step r2: SELECT TRUE;
-bool
-----
-t   
+?column?
+--------
+t       
 (1 row)
 
 step wxry1: INSERT INTO child (parent_id) VALUES (0);
@@ -80,9 +80,9 @@ ERROR:  could not serialize access due to read/write dependencies among transact
 
 starting permutation: r2 wxry1 wyrx2 c2 c1
 step r2: SELECT TRUE;
-bool
-----
-t   
+?column?
+--------
+t       
 (1 row)
 
 step wxry1: INSERT INTO child (parent_id) VALUES (0);
@@ -93,9 +93,9 @@ ERROR:  could not serialize access due to read/write dependencies among transact
 
 starting permutation: r2 wyrx2 wxry1 c1 c2
 step r2: SELECT TRUE;
-bool
-----
-t   
+?column?
+--------
+t       
 (1 row)
 
 step wyrx2: DELETE FROM parent WHERE parent_id = 0;
@@ -106,9 +106,9 @@ ERROR:  could not serialize access due to read/write dependencies among transact
 
 starting permutation: r2 wyrx2 wxry1 c2 c1
 step r2: SELECT TRUE;
-bool
-----
-t   
+?column?
+--------
+t       
 (1 row)
 
 step wyrx2: DELETE FROM parent WHERE parent_id = 0;
@@ -119,9 +119,9 @@ ERROR:  could not serialize access due to read/write dependencies among transact
 
 starting permutation: r2 wyrx2 c2 wxry1 c1
 step r2: SELECT TRUE;
-bool
-----
-t   
+?column?
+--------
+t       
 (1 row)
 
 step wyrx2: DELETE FROM parent WHERE parent_id = 0;
index 3a4fd451471370c2964e58ea6735c0e9647812cf..e0c4bee8938c447f381c456b8e67ebae6fc30f3b 100644 (file)
@@ -403,7 +403,7 @@ SELECT pg_get_functiondef('functest_S_13'::regproc);
   LANGUAGE sql                                            +
  BEGIN ATOMIC                                             +
   SELECT 1;                                               +
-  SELECT false AS bool;                                   +
+  SELECT false;                                           +
  END                                                      +
  
 (1 row)