diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 09a3f5e23cb..bf3f3d9e26e 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -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 diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index ce1a9df2688..0755ab1eae5 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -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: diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 119b7959827..25b75375a8e 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -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), diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index f2ffd42a05f..27cb6307581 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -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, diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index 39f0bf7a0d4..4cc4e3c00f8 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -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), diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 5f6e94949b1..f9d3c1246bb 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -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; } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index b105c263810..90b5da51c95 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -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; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index ae37ea9464b..06345da3ba8 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -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; diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index acc17da7177..47d0564fa29 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -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: diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index d28cea15670..2b0236937aa 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -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)) diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c index 0460aad6ea5..8435203f2bd 100644 --- a/src/backend/nodes/read.c +++ b/src/backend/nodes/read.c @@ -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)); diff --git a/src/backend/nodes/value.c b/src/backend/nodes/value.c index 6905cae6d31..6fe55f5dd5c 100644 --- a/src/backend/nodes/value.c +++ b/src/backend/nodes/value.c @@ -42,6 +42,18 @@ makeFloat(char *numericStr) return v; } +/* + * makeBoolean + */ +Boolean * +makeBoolean(bool val) +{ + Boolean *v = makeNode(Boolean); + + v->boolval = val; + return v; +} + /* * makeString * diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index bb015a8bbd3..b5966712ce1 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -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 */ diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index 95913c80215..35db6b6c988 100644 --- a/src/backend/parser/parse_node.c +++ b/src/backend/parser/parse_node.c @@ -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: /* diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y index 8800d10d5fe..6d1dbd72e91 100644 --- a/src/backend/replication/repl_gram.y +++ b/src/backend/replication/repl_gram.y @@ -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); } ; diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 28cf5aefcae..f9ddafd3459 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -292,6 +292,7 @@ typedef enum NodeTag */ T_Integer, T_Float, + T_Boolean, T_String, T_BitString, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 413e7c85a1e..3e9bdc781f9 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -304,6 +304,7 @@ typedef struct A_Const Node node; Integer ival; Float fval; + Boolean boolval; String sval; BitString bsval; } val; diff --git a/src/include/nodes/value.h b/src/include/nodes/value.h index 442cc19fcba..eaf937051c3 100644 --- a/src/include/nodes/value.h +++ b/src/include/nodes/value.h @@ -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); diff --git a/src/test/isolation/expected/ri-trigger.out b/src/test/isolation/expected/ri-trigger.out index 842df80a90b..db85618bef7 100644 --- a/src/test/isolation/expected/ri-trigger.out +++ b/src/test/isolation/expected/ri-trigger.out @@ -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; diff --git a/src/test/regress/expected/create_function_3.out b/src/test/regress/expected/create_function_3.out index 3a4fd451471..e0c4bee8938 100644 --- a/src/test/regress/expected/create_function_3.out +++ b/src/test/regress/expected/create_function_3.out @@ -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)