aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_node.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2021-09-09 07:58:12 +0200
committerPeter Eisentraut <peter@eisentraut.org>2021-09-09 08:36:53 +0200
commit639a86e36aaecb84faaf941dcd0b183ba0aba9e9 (patch)
tree2b523f247bf373ae61fcff5fb0bf938c6c5bdc07 /src/backend/parser/parse_node.c
parentcbdf75bf8053f88bbae6b307f34ab057424a370f (diff)
downloadpostgresql-639a86e36aaecb84faaf941dcd0b183ba0aba9e9.tar.gz
postgresql-639a86e36aaecb84faaf941dcd0b183ba0aba9e9.zip
Remove Value node struct
The Value node struct is a weird construct. It is its own node type, but most of the time, it actually has a node type of Integer, Float, String, or BitString. As a consequence, the struct name and the node type don't match most of the time, and so it has to be treated specially a lot. There doesn't seem to be any value in the special construct. There is very little code that wants to accept all Value variants but nothing else (and even if it did, this doesn't provide any convenient way to check it), and most code wants either just one particular node type (usually String), or it accepts a broader set of node types besides just Value. This change removes the Value struct and node type and replaces them by separate Integer, Float, String, and BitString node types that are proper node types and structs of their own and behave mostly like normal node types. Also, this removes the T_Null node tag, which was previously also a possible variant of Value but wasn't actually used outside of the Value contained in A_Const. Replace that by an isnull field in A_Const. Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org> Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/5ba6bc5b-3f95-04f2-2419-f8ddb4c046fb@enterprisedb.com
Diffstat (limited to 'src/backend/parser/parse_node.c')
-rw-r--r--src/backend/parser/parse_node.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index 17c900da31b..8cfe6f67c04 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -333,7 +333,7 @@ transformContainerSubscripts(ParseState *pstate,
/*
* make_const
*
- * Convert a Value node (as returned by the grammar) to a Const node
+ * Convert an A_Const node (as returned by the grammar) to a Const node
* of the "natural" type for the constant. Note that this routine is
* only used when there is no explicit cast for the constant, so we
* have to guess what type is wanted.
@@ -349,7 +349,7 @@ transformContainerSubscripts(ParseState *pstate,
* too many examples that fail if we try.
*/
Const *
-make_const(ParseState *pstate, Value *value, int location)
+make_const(ParseState *pstate, A_Const *aconst)
{
Const *con;
Datum val;
@@ -359,10 +359,24 @@ make_const(ParseState *pstate, Value *value, int location)
bool typebyval;
ParseCallbackState pcbstate;
- switch (nodeTag(value))
+ if (aconst->isnull)
+ {
+ /* return a null const */
+ con = makeConst(UNKNOWNOID,
+ -1,
+ InvalidOid,
+ -2,
+ (Datum) 0,
+ true,
+ false);
+ con->location = aconst->location;
+ return con;
+ }
+
+ switch (nodeTag(&aconst->val))
{
case T_Integer:
- val = Int32GetDatum(intVal(value));
+ val = Int32GetDatum(aconst->val.ival.val);
typeid = INT4OID;
typelen = sizeof(int32);
@@ -371,7 +385,7 @@ make_const(ParseState *pstate, Value *value, int location)
case T_Float:
/* could be an oversize integer as well as a float ... */
- if (scanint8(strVal(value), true, &val64))
+ if (scanint8(aconst->val.fval.val, true, &val64))
{
/*
* It might actually fit in int32. Probably only INT_MIN can
@@ -399,9 +413,9 @@ make_const(ParseState *pstate, Value *value, int location)
else
{
/* arrange to report location if numeric_in() fails */
- setup_parser_errposition_callback(&pcbstate, pstate, location);
+ setup_parser_errposition_callback(&pcbstate, pstate, aconst->location);
val = DirectFunctionCall3(numeric_in,
- CStringGetDatum(strVal(value)),
+ CStringGetDatum(aconst->val.fval.val),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));
cancel_parser_errposition_callback(&pcbstate);
@@ -418,7 +432,7 @@ make_const(ParseState *pstate, Value *value, int location)
* We assume here that UNKNOWN's internal representation is the
* same as CSTRING
*/
- val = CStringGetDatum(strVal(value));
+ val = CStringGetDatum(aconst->val.sval.val);
typeid = UNKNOWNOID; /* will be coerced later */
typelen = -2; /* cstring-style varwidth type */
@@ -427,9 +441,9 @@ make_const(ParseState *pstate, Value *value, int location)
case T_BitString:
/* arrange to report location if bit_in() fails */
- setup_parser_errposition_callback(&pcbstate, pstate, location);
+ setup_parser_errposition_callback(&pcbstate, pstate, aconst->location);
val = DirectFunctionCall3(bit_in,
- CStringGetDatum(strVal(value)),
+ CStringGetDatum(aconst->val.bsval.val),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));
cancel_parser_errposition_callback(&pcbstate);
@@ -438,20 +452,8 @@ make_const(ParseState *pstate, Value *value, int location)
typebyval = false;
break;
- case T_Null:
- /* return a null const */
- con = makeConst(UNKNOWNOID,
- -1,
- InvalidOid,
- -2,
- (Datum) 0,
- true,
- false);
- con->location = location;
- return con;
-
default:
- elog(ERROR, "unrecognized node type: %d", (int) nodeTag(value));
+ elog(ERROR, "unrecognized node type: %d", (int) nodeTag(&aconst->val));
return NULL; /* keep compiler quiet */
}
@@ -462,7 +464,7 @@ make_const(ParseState *pstate, Value *value, int location)
val,
false,
typebyval);
- con->location = location;
+ con->location = aconst->location;
return con;
}