Remove Value node struct
authorPeter Eisentraut <[email protected]>
Thu, 9 Sep 2021 05:58:12 +0000 (07:58 +0200)
committerPeter Eisentraut <[email protected]>
Thu, 9 Sep 2021 06:36:53 +0000 (08:36 +0200)
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 <[email protected]>
Reviewed-by: Kyotaro Horiguchi <[email protected]>
Discussion: https://www.postgresql.org/message-id/flat/5ba6bc5b-3f95-04f2-2419-f8ddb4c046fb@enterprisedb.com

30 files changed:
contrib/postgres_fdw/postgres_fdw.c
src/backend/catalog/namespace.c
src/backend/catalog/objectaddress.c
src/backend/catalog/pg_enum.c
src/backend/commands/copy.c
src/backend/commands/define.c
src/backend/commands/tsearchcmds.c
src/backend/executor/nodeTableFuncscan.c
src/backend/nodes/README
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/nodeFuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/value.c
src/backend/parser/gram.y
src/backend/parser/parse_clause.c
src/backend/parser/parse_cte.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_node.c
src/backend/parser/parse_relation.c
src/backend/parser/parse_type.c
src/backend/parser/parse_utilcmd.c
src/backend/utils/adt/oid.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/misc/guc.c
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/nodes/primnodes.h
src/include/nodes/value.h
src/include/parser/parse_node.h

index 4bdab30a7346eef79658fc1c3bfb3df54cff5aea..76d4fea21c4df1d18ea9877ae3568990d5579d5f 100644 (file)
@@ -101,9 +101,9 @@ enum FdwModifyPrivateIndex
        FdwModifyPrivateUpdateSql,
        /* Integer list of target attribute numbers for INSERT/UPDATE */
        FdwModifyPrivateTargetAttnums,
-       /* Length till the end of VALUES clause (as an integer Value node) */
+       /* Length till the end of VALUES clause (as an Integer node) */
        FdwModifyPrivateLen,
-       /* has-returning flag (as an integer Value node) */
+       /* has-returning flag (as an Integer 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 Value node) */
+       /* has-returning flag (as an Integer node) */
        FdwDirectModifyPrivateHasReturning,
        /* Integer list of attribute numbers retrieved by RETURNING */
        FdwDirectModifyPrivateRetrievedAttrs,
-       /* set-processed flag (as an integer Value node) */
+       /* set-processed flag (as an Integer node) */
        FdwDirectModifyPrivateSetProcessed
 };
 
@@ -280,9 +280,9 @@ typedef struct PgFdwAnalyzeState
  */
 enum FdwPathPrivateIndex
 {
-       /* has-final-sort flag (as an integer Value node) */
+       /* has-final-sort flag (as an Integer node) */
        FdwPathPrivateHasFinalSort,
-       /* has-limit flag (as an integer Value node) */
+       /* has-limit flag (as an Integer node) */
        FdwPathPrivateHasLimit
 };
 
index fd767fc5cfa29860152ecf8e21b9973906cca48c..4de8400fd0f080ee865787ada74dcba1a227b4b1 100644 (file)
@@ -3026,7 +3026,7 @@ CheckSetNamespace(Oid oldNspOid, Oid nspOid)
 
 /*
  * QualifiedNameGetCreationNamespace
- *             Given a possibly-qualified name for an object (in List-of-Values
+ *             Given a possibly-qualified name for an object (in List-of-Strings
  *             format), determine what namespace the object should be created in.
  *             Also extract and return the object name (last component of list).
  *
@@ -3140,7 +3140,7 @@ makeRangeVarFromNameList(List *names)
  * This is used primarily to form error messages, and so we do not quote
  * the list elements, for the sake of legibility.
  *
- * In most scenarios the list elements should always be Value strings,
+ * In most scenarios the list elements should always be String values,
  * but we also allow A_Star for the convenience of ColumnRef processing.
  */
 char *
index bc2a4ccdde02f1cc7bd9adcd3c7cd9cb9ea2bf6f..8c94939baa81eff1b05fab5e6b0de38a617db0f2 100644 (file)
@@ -851,7 +851,7 @@ const ObjectAddress InvalidObjectAddress =
 };
 
 static ObjectAddress get_object_address_unqualified(ObjectType objtype,
-                                                                                                       Value *strval, bool missing_ok);
+                                                                                                       String *strval, bool missing_ok);
 static ObjectAddress get_relation_by_qualified_name(ObjectType objtype,
                                                                                                        List *object, Relation *relp,
                                                                                                        LOCKMODE lockmode, bool missing_ok);
@@ -1011,7 +1011,7 @@ get_object_address(ObjectType objtype, Node *object,
                        case OBJECT_PUBLICATION:
                        case OBJECT_SUBSCRIPTION:
                                address = get_object_address_unqualified(objtype,
-                                                                                                                (Value *) object, missing_ok);
+                                                                                                                castNode(String, object), missing_ok);
                                break;
                        case OBJECT_TYPE:
                        case OBJECT_DOMAIN:
@@ -1244,7 +1244,7 @@ get_object_address_rv(ObjectType objtype, RangeVar *rel, List *object,
  */
 static ObjectAddress
 get_object_address_unqualified(ObjectType objtype,
-                                                          Value *strval, bool missing_ok)
+                                                          String *strval, bool missing_ok)
 {
        const char *name;
        ObjectAddress address;
index f958f1541dec42dfee890ceb9445a5873437da4c..be1c5a5b0d7c7319723af47d066486486cf0074a 100644 (file)
@@ -55,7 +55,7 @@ static int    sort_order_cmp(const void *p1, const void *p2);
  * EnumValuesCreate
  *             Create an entry in pg_enum for each of the supplied enum values.
  *
- * vals is a list of Value strings.
+ * vals is a list of String values.
  */
 void
 EnumValuesCreate(Oid enumTypeOid, List *vals)
index 6b33951e0c9a70afacde0db9f42c77c27e8ecc14..53f485314194710802702fd1ef9261922cb92c65 100644 (file)
@@ -222,9 +222,8 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
                                {
                                        /*
                                         * Build the ColumnRef for each column.  The ColumnRef
-                                        * 'fields' property is a String 'Value' node (see
-                                        * nodes/value.h) that corresponds to the column name
-                                        * respectively.
+                                        * 'fields' property is a String node that corresponds to
+                                        * the column name respectively.
                                         */
                                        cr = makeNode(ColumnRef);
                                        cr->fields = list_make1(lfirst(lc));
index aafd7554e4eb9d02fc08e43c3f4ef7d78c3adf54..19c317a472e7f8f0dc524903d9db3ef00d0b5fec 100644 (file)
@@ -58,12 +58,7 @@ defGetString(DefElem *def)
                case T_Integer:
                        return psprintf("%ld", (long) intVal(def->arg));
                case T_Float:
-
-                       /*
-                        * T_Float values are kept in string form, so this type cheat
-                        * works (and doesn't risk losing precision)
-                        */
-                       return strVal(def->arg);
+                       return castNode(Float, def->arg)->val;
                case T_String:
                        return strVal(def->arg);
                case T_TypeName:
@@ -206,7 +201,7 @@ defGetInt64(DefElem *def)
                         * strings.
                         */
                        return DatumGetInt64(DirectFunctionCall1(int8in,
-                                                                                                        CStringGetDatum(strVal(def->arg))));
+                                                                                                        CStringGetDatum(castNode(Float, def->arg)->val)));
                default:
                        ereport(ERROR,
                                        (errcode(ERRCODE_SYNTAX_ERROR),
index e06fb32b3d1ec03383aa267749f76ecf4f44e263..c47a05d10da556d74ce121167042e7dd0310f8fd 100644 (file)
@@ -1179,7 +1179,7 @@ getTokenTypes(Oid prsId, List *tokennames)
        i = 0;
        foreach(tn, tokennames)
        {
-               Value      *val = (Value *) lfirst(tn);
+               String     *val = lfirst_node(String, tn);
                bool            found = false;
                int                     j;
 
@@ -1395,7 +1395,7 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
        i = 0;
        foreach(c, stmt->tokentype)
        {
-               Value      *val = (Value *) lfirst(c);
+               String     *val = lfirst_node(String, c);
                bool            found = false;
 
                ScanKeyInit(&skey[0],
index 4d7eca4acedfaee4112eefeaea9a750f2684a9b4..27dfa1b9564525195e151222867899f4c855e985 100644 (file)
@@ -364,7 +364,7 @@ tfuncInitialize(TableFuncScanState *tstate, ExprContext *econtext, Datum doc)
        forboth(lc1, tstate->ns_uris, lc2, tstate->ns_names)
        {
                ExprState  *expr = (ExprState *) lfirst(lc1);
-               Value      *ns_node = (Value *) lfirst(lc2);
+               String     *ns_node = lfirst_node(String, lc2);
                char       *ns_uri;
                char       *ns_name;
 
index dcd66d7243c06767221befda292b263491c8856a..d066ac5c61795b1c0ccbe6235d315733a2caaf1e 100644 (file)
@@ -28,7 +28,7 @@ FILES IN THIS DIRECTORY (src/backend/nodes/)
        list.c          - generic list support
        params.c        - Param support
        tidbitmap.c     - TIDBitmap support
-       value.c         - support for Value nodes
+       value.c         - support for value nodes
 
 FILES IN src/include/nodes/
 
index e308de170e922f8dc509071958f9d59cdba57468..83ec2a369e89548c1dc3c278a022d15fe08fed2d 100644 (file)
@@ -2729,25 +2729,30 @@ _copyA_Const(const A_Const *from)
 {
        A_Const    *newnode = makeNode(A_Const);
 
-       /* This part must duplicate _copyValue */
-       COPY_SCALAR_FIELD(val.type);
-       switch (from->val.type)
+       COPY_SCALAR_FIELD(isnull);
+       if (!from->isnull)
        {
-               case T_Integer:
-                       COPY_SCALAR_FIELD(val.val.ival);
-                       break;
-               case T_Float:
-               case T_String:
-               case T_BitString:
-                       COPY_STRING_FIELD(val.val.str);
-                       break;
-               case T_Null:
-                       /* nothing to do */
-                       break;
-               default:
-                       elog(ERROR, "unrecognized node type: %d",
-                                (int) from->val.type);
-                       break;
+               /* This part must duplicate other _copy*() functions. */
+               COPY_SCALAR_FIELD(val.node.type);
+               switch (nodeTag(&from->val))
+               {
+                       case T_Integer:
+                               COPY_SCALAR_FIELD(val.ival.val);
+                               break;
+                       case T_Float:
+                               COPY_STRING_FIELD(val.fval.val);
+                               break;
+                       case T_String:
+                               COPY_STRING_FIELD(val.sval.val);
+                               break;
+                       case T_BitString:
+                               COPY_STRING_FIELD(val.bsval.val);
+                               break;
+                       default:
+                               elog(ERROR, "unrecognized node type: %d",
+                                        (int) nodeTag(&from->val));
+                               break;
+               }
        }
 
        COPY_LOCATION_FIELD(location);
@@ -4892,32 +4897,43 @@ _copyExtensibleNode(const ExtensibleNode *from)
  *                                     value.h copy functions
  * ****************************************************************
  */
-static Value *
-_copyValue(const Value *from)
+static Integer *
+_copyInteger(const Integer *from)
 {
-       Value      *newnode = makeNode(Value);
+       Integer    *newnode = makeNode(Integer);
 
-       /* See also _copyAConst when changing this code! */
+       COPY_SCALAR_FIELD(val);
+
+       return newnode;
+}
+
+static Float *
+_copyFloat(const Float *from)
+{
+       Float      *newnode = makeNode(Float);
+
+       COPY_STRING_FIELD(val);
+
+       return newnode;
+}
+
+static String *
+_copyString(const String *from)
+{
+       String     *newnode = makeNode(String);
+
+       COPY_STRING_FIELD(val);
+
+       return newnode;
+}
+
+static BitString *
+_copyBitString(const BitString *from)
+{
+       BitString   *newnode = makeNode(BitString);
+
+       COPY_STRING_FIELD(val);
 
-       COPY_SCALAR_FIELD(type);
-       switch (from->type)
-       {
-               case T_Integer:
-                       COPY_SCALAR_FIELD(val.ival);
-                       break;
-               case T_Float:
-               case T_String:
-               case T_BitString:
-                       COPY_STRING_FIELD(val.str);
-                       break;
-               case T_Null:
-                       /* nothing to do */
-                       break;
-               default:
-                       elog(ERROR, "unrecognized node type: %d",
-                                (int) from->type);
-                       break;
-       }
        return newnode;
 }
 
@@ -5314,11 +5330,16 @@ copyObjectImpl(const void *from)
                         * VALUE NODES
                         */
                case T_Integer:
+                       retval = _copyInteger(from);
+                       break;
                case T_Float:
+                       retval = _copyFloat(from);
+                       break;
                case T_String:
+                       retval = _copyString(from);
+                       break;
                case T_BitString:
-               case T_Null:
-                       retval = _copyValue(from);
+                       retval = _copyBitString(from);
                        break;
 
                        /*
index 99440b40be042ac9e1a09988383256f096dc5581..231380ccf7402d92aabfcf25c4739a47d7f18915 100644 (file)
@@ -2409,7 +2409,7 @@ _equalParamRef(const ParamRef *a, const ParamRef *b)
 static bool
 _equalA_Const(const A_Const *a, const A_Const *b)
 {
-       if (!equal(&a->val, &b->val))   /* hack for in-line Value field */
+       if (!equal(&a->val, &b->val))   /* hack for in-line val field */
                return false;
        COMPARE_LOCATION_FIELD(location);
 
@@ -3089,27 +3089,33 @@ _equalList(const List *a, const List *b)
  */
 
 static bool
-_equalValue(const Value *a, const Value *b)
+_equalInteger(const Integer *a, const Integer *b)
 {
-       COMPARE_SCALAR_FIELD(type);
+       COMPARE_SCALAR_FIELD(val);
 
-       switch (a->type)
-       {
-               case T_Integer:
-                       COMPARE_SCALAR_FIELD(val.ival);
-                       break;
-               case T_Float:
-               case T_String:
-               case T_BitString:
-                       COMPARE_STRING_FIELD(val.str);
-                       break;
-               case T_Null:
-                       /* nothing to do */
-                       break;
-               default:
-                       elog(ERROR, "unrecognized node type: %d", (int) a->type);
-                       break;
-       }
+       return true;
+}
+
+static bool
+_equalFloat(const Float *a, const Float *b)
+{
+       COMPARE_STRING_FIELD(val);
+
+       return true;
+}
+
+static bool
+_equalString(const String *a, const String *b)
+{
+       COMPARE_STRING_FIELD(val);
+
+       return true;
+}
+
+static bool
+_equalBitString(const BitString *a, const BitString *b)
+{
+       COMPARE_STRING_FIELD(val);
 
        return true;
 }
@@ -3337,11 +3343,16 @@ equal(const void *a, const void *b)
                        break;
 
                case T_Integer:
+                       retval = _equalInteger(a, b);
+                       break;
                case T_Float:
+                       retval = _equalFloat(a, b);
+                       break;
                case T_String:
+                       retval = _equalString(a, b);
+                       break;
                case T_BitString:
-               case T_Null:
-                       retval = _equalValue(a, b);
+                       retval = _equalBitString(a, b);
                        break;
 
                        /*
index ff3dcc7b18baaa130f16adadf0a749782e20ac97..e2762648829ef99c088247b81a65e810980116f0 100644 (file)
@@ -3537,7 +3537,6 @@ raw_expression_tree_walker(Node *node,
                case T_Float:
                case T_String:
                case T_BitString:
-               case T_Null:
                case T_ParamRef:
                case T_A_Const:
                case T_A_Star:
index 87561cbb6f1976ebf1d0d3168bb97f1c125294bf..36e618611fd16125a4a72e4fbeedc703e598c9d3 100644 (file)
@@ -3414,44 +3414,39 @@ _outA_Expr(StringInfo str, const A_Expr *node)
 }
 
 static void
-_outValue(StringInfo str, const Value *node)
+_outInteger(StringInfo str, const Integer *node)
 {
-       switch (node->type)
-       {
-               case T_Integer:
-                       appendStringInfo(str, "%d", node->val.ival);
-                       break;
-               case T_Float:
+       appendStringInfo(str, "%d", node->val);
+}
 
-                       /*
-                        * We assume the value is a valid numeric literal and so does not
-                        * need quoting.
-                        */
-                       appendStringInfoString(str, node->val.str);
-                       break;
-               case T_String:
-
-                       /*
-                        * We use outToken to provide escaping of the string's content,
-                        * but we don't want it to do anything with an empty string.
-                        */
-                       appendStringInfoChar(str, '"');
-                       if (node->val.str[0] != '\0')
-                               outToken(str, node->val.str);
-                       appendStringInfoChar(str, '"');
-                       break;
-               case T_BitString:
-                       /* internal representation already has leading 'b' */
-                       appendStringInfoString(str, node->val.str);
-                       break;
-               case T_Null:
-                       /* this is seen only within A_Const, not in transformed trees */
-                       appendStringInfoString(str, "NULL");
-                       break;
-               default:
-                       elog(ERROR, "unrecognized node type: %d", (int) node->type);
-                       break;
-       }
+static void
+_outFloat(StringInfo str, const Float *node)
+{
+       /*
+        * We assume the value is a valid numeric literal and so does not
+        * need quoting.
+        */
+       appendStringInfoString(str, node->val);
+}
+
+static void
+_outString(StringInfo str, const String *node)
+{
+       /*
+        * We use outToken to provide escaping of the string's content,
+        * but we don't want it to do anything with an empty string.
+        */
+       appendStringInfoChar(str, '"');
+       if (node->val[0] != '\0')
+               outToken(str, node->val);
+       appendStringInfoChar(str, '"');
+}
+
+static void
+_outBitString(StringInfo str, const BitString *node)
+{
+       /* internal representation already has leading 'b' */
+       appendStringInfoString(str, node->val);
 }
 
 static void
@@ -3491,8 +3486,13 @@ _outA_Const(StringInfo str, const A_Const *node)
 {
        WRITE_NODE_TYPE("A_CONST");
 
-       appendStringInfoString(str, " :val ");
-       _outValue(str, &(node->val));
+       if (node->isnull)
+               appendStringInfoString(str, "NULL");
+       else
+       {
+               appendStringInfoString(str, " :val ");
+               outNode(str, &node->val);
+       }
        WRITE_LOCATION_FIELD(location);
 }
 
@@ -3835,14 +3835,15 @@ outNode(StringInfo str, const void *obj)
                appendStringInfoString(str, "<>");
        else if (IsA(obj, List) || IsA(obj, IntList) || IsA(obj, OidList))
                _outList(str, obj);
-       else if (IsA(obj, Integer) ||
-                        IsA(obj, Float) ||
-                        IsA(obj, String) ||
-                        IsA(obj, BitString))
-       {
-               /* nodeRead does not want to see { } around these! */
-               _outValue(str, obj);
-       }
+       /* nodeRead does not want to see { } around these! */
+       else if (IsA(obj, Integer))
+               _outInteger(str, (Integer *) obj);
+       else if (IsA(obj, Float))
+               _outFloat(str, (Float *) obj);
+       else if (IsA(obj, String))
+               _outString(str, (String *) obj);
+       else if (IsA(obj, BitString))
+               _outBitString(str, (BitString *) obj);
        else
        {
                appendStringInfoChar(str, '{');
index 15e6d26752186fe8310fe8ef093da10d3dc6678e..515f93c22374ad53d2ef5b79327f3ce199d42751 100644 (file)
@@ -1,7 +1,7 @@
 /*-------------------------------------------------------------------------
  *
  * value.c
- *       implementation of Value nodes
+ *       implementation of value nodes
  *
  *
  * Copyright (c) 2003-2021, PostgreSQL Global Development Group
  */
 #include "postgres.h"
 
-#include "nodes/parsenodes.h"
+#include "nodes/value.h"
 
 /*
  *     makeInteger
  */
-Value *
+Integer *
 makeInteger(int i)
 {
-       Value      *v = makeNode(Value);
+       Integer    *v = makeNode(Integer);
 
-       v->type = T_Integer;
-       v->val.ival = i;
+       v->val = i;
        return v;
 }
 
@@ -34,13 +33,12 @@ makeInteger(int i)
  *
  * Caller is responsible for passing a palloc'd string.
  */
-Value *
+Float *
 makeFloat(char *numericStr)
 {
-       Value      *v = makeNode(Value);
+       Float      *v = makeNode(Float);
 
-       v->type = T_Float;
-       v->val.str = numericStr;
+       v->val = numericStr;
        return v;
 }
 
@@ -49,13 +47,12 @@ makeFloat(char *numericStr)
  *
  * Caller is responsible for passing a palloc'd string.
  */
-Value *
+String *
 makeString(char *str)
 {
-       Value      *v = makeNode(Value);
+       String     *v = makeNode(String);
 
-       v->type = T_String;
-       v->val.str = str;
+       v->val = str;
        return v;
 }
 
@@ -64,12 +61,11 @@ makeString(char *str)
  *
  * Caller is responsible for passing a palloc'd string.
  */
-Value *
+BitString *
 makeBitString(char *str)
 {
-       Value      *v = makeNode(Value);
+       BitString  *v = makeNode(BitString);
 
-       v->type = T_BitString;
-       v->val.str = str;
+       v->val = str;
        return v;
 }
index 6a0f46505c5c875c7b4d18c9fd54c95f13590c1f..e3068a374ee42366a0a26374041044c5ab765305 100644 (file)
@@ -166,7 +166,7 @@ static Node *makeIntConst(int val, int location);
 static Node *makeFloatConst(char *str, int location);
 static Node *makeBitStringConst(char *str, int location);
 static Node *makeNullAConst(int location);
-static Node *makeAConst(Value *v, 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);
@@ -183,7 +183,7 @@ static void insertSelectOptions(SelectStmt *stmt,
                                                                core_yyscan_t yyscanner);
 static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
 static Node *doNegate(Node *n, int location);
-static void doNegateFloat(Value *v);
+static void doNegateFloat(Float *v);
 static Node *makeAndExpr(Node *lexpr, Node *rexpr, int location);
 static Node *makeOrExpr(Node *lexpr, Node *rexpr, int location);
 static Node *makeNotExpr(Node *expr, int location);
@@ -228,7 +228,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
        OnCommitAction          oncommit;
        List                            *list;
        Node                            *node;
-       Value                           *value;
        ObjectType                      objtype;
        TypeName                        *typnam;
        FunctionParameter   *fun_param;
@@ -351,7 +350,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <boolean> TriggerForSpec TriggerForType
 %type <ival>   TriggerActionTime
 %type <list>   TriggerEvents TriggerOneEvent
-%type <value>  TriggerFuncArg
+%type <node>   TriggerFuncArg
 %type <node>   TriggerWhen
 %type <str>            TransitionRelName
 %type <boolean>        TransitionRowOrTable TransitionOldOrNew
@@ -508,7 +507,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <list>   when_clause_list
 %type <node>   opt_search_clause opt_cycle_clause
 %type <ival>   sub_type opt_materialized
-%type <value>  NumericOnly
+%type <node>   NumericOnly
 %type <list>   NumericOnly_list
 %type <alias>  alias_clause opt_alias_clause opt_alias_clause_for_join_using
 %type <list>   func_alias_clause
@@ -1696,7 +1695,7 @@ zone_value:
                                        if ($3 != NIL)
                                        {
                                                A_Const *n = (A_Const *) linitial($3);
-                                               if ((n->val.val.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)
+                                               if ((n->val.ival.val & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)
                                                        ereport(ERROR,
                                                                        (errcode(ERRCODE_SYNTAX_ERROR),
                                                                         errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
@@ -4459,14 +4458,15 @@ opt_by:         BY
          ;
 
 NumericOnly:
-                       FCONST                                                          { $$ = makeFloat($1); }
-                       | '+' FCONST                                            { $$ = makeFloat($2); }
+                       FCONST                                                          { $$ = (Node *) makeFloat($1); }
+                       | '+' FCONST                                            { $$ = (Node *) makeFloat($2); }
                        | '-' FCONST
                                {
-                                       $$ = makeFloat($2);
-                                       doNegateFloat($$);
+                                       Float *f = makeFloat($2);
+                                       doNegateFloat(f);
+                                       $$ = (Node *) f;
                                }
-                       | SignedIconst                                          { $$ = makeInteger($1); }
+                       | SignedIconst                                          { $$ = (Node *) makeInteger($1); }
                ;
 
 NumericOnly_list:      NumericOnly                                             { $$ = list_make1($1); }
@@ -5535,11 +5535,11 @@ TriggerFuncArgs:
 TriggerFuncArg:
                        Iconst
                                {
-                                       $$ = makeString(psprintf("%d", $1));
+                                       $$ = (Node *) makeString(psprintf("%d", $1));
                                }
-                       | FCONST                                                                { $$ = makeString($1); }
-                       | Sconst                                                                { $$ = makeString($1); }
-                       | ColLabel                                                              { $$ = makeString($1); }
+                       | FCONST                                                                { $$ = (Node *) makeString($1); }
+                       | Sconst                                                                { $$ = (Node *) makeString($1); }
+                       | ColLabel                                                              { $$ = (Node *) makeString($1); }
                ;
 
 OptConstrFromTable:
@@ -7773,8 +7773,8 @@ aggr_arg: func_arg
  *
  * The return value of this production is a two-element list, in which the
  * first item is a sublist of FunctionParameter nodes (with any duplicate
- * VARIADIC item already dropped, as per above) and the second is an integer
- * Value node, containing -1 if there was no ORDER BY and otherwise the number
+ * VARIADIC item already dropped, as per above) and the second is an Integer
+ * node, containing -1 if there was no ORDER BY and otherwise the number
  * of argument declarations before the ORDER BY.  (If this number is equal
  * to the first sublist's length, then we dropped a duplicate VARIADIC item.)
  * This representation is passed as-is to CREATE AGGREGATE; for operations
@@ -16520,11 +16520,11 @@ makeStringConst(char *str, int location)
 {
        A_Const *n = makeNode(A_Const);
 
-       n->val.type = T_String;
-       n->val.val.str = str;
+       n->val.sval.type = T_String;
+       n->val.sval.val = str;
        n->location = location;
 
-       return (Node *)n;
+   return (Node *)n;
 }
 
 static Node *
@@ -16540,11 +16540,11 @@ makeIntConst(int val, int location)
 {
        A_Const *n = makeNode(A_Const);
 
-       n->val.type = T_Integer;
-       n->val.val.ival = val;
+       n->val.ival.type = T_Integer;
+       n->val.ival.val = val;
        n->location = location;
 
-       return (Node *)n;
+   return (Node *)n;
 }
 
 static Node *
@@ -16552,11 +16552,11 @@ makeFloatConst(char *str, int location)
 {
        A_Const *n = makeNode(A_Const);
 
-       n->val.type = T_Float;
-       n->val.val.str = str;
+       n->val.fval.type = T_Float;
+       n->val.fval.val = str;
        n->location = location;
 
-       return (Node *)n;
+   return (Node *)n;
 }
 
 static Node *
@@ -16564,11 +16564,11 @@ makeBitStringConst(char *str, int location)
 {
        A_Const *n = makeNode(A_Const);
 
-       n->val.type = T_BitString;
-       n->val.val.str = str;
+       n->val.bsval.type = T_BitString;
+       n->val.bsval.val = str;
        n->location = location;
 
-       return (Node *)n;
+   return (Node *)n;
 }
 
 static Node *
@@ -16576,30 +16576,30 @@ makeNullAConst(int location)
 {
        A_Const *n = makeNode(A_Const);
 
-       n->val.type = T_Null;
+       n->isnull = true;
        n->location = location;
 
        return (Node *)n;
 }
 
 static Node *
-makeAConst(Value *v, int location)
+makeAConst(Node *v, int location)
 {
        Node *n;
 
        switch (v->type)
        {
                case T_Float:
-                       n = makeFloatConst(v->val.str, location);
+                       n = makeFloatConst(castNode(Float, v)->val, location);
                        break;
 
                case T_Integer:
-                       n = makeIntConst(v->val.ival, location);
+                       n = makeIntConst(castNode(Integer, v)->val, location);
                        break;
 
                case T_String:
                default:
-                       n = makeStringConst(v->val.str, location);
+                       n = makeStringConst(castNode(String, v)->val, location);
                        break;
        }
 
@@ -16612,13 +16612,9 @@ makeAConst(Value *v, int location)
 static Node *
 makeBoolAConst(bool state, int location)
 {
-       A_Const *n = makeNode(A_Const);
-
-       n->val.type = T_String;
-       n->val.val.str = (state ? "t" : "f");
-       n->location = location;
-
-       return makeTypeCast((Node *)n, SystemTypeName("bool"), -1);
+       return makeStringConstCast((state ? "t" : "f"),
+                                                          location,
+                                                          SystemTypeName("bool"));
 }
 
 /* makeRoleSpec
@@ -16733,7 +16729,7 @@ makeOrderedSetArgs(List *directargs, List *orderedargs,
                                   core_yyscan_t yyscanner)
 {
        FunctionParameter *lastd = (FunctionParameter *) llast(directargs);
-       Value      *ndirectargs;
+       Integer    *ndirectargs;
 
        /* No restriction unless last direct arg is VARIADIC */
        if (lastd->mode == FUNC_PARAM_VARIADIC)
@@ -16890,14 +16886,14 @@ doNegate(Node *n, int location)
                /* report the constant's location as that of the '-' sign */
                con->location = location;
 
-               if (con->val.type == T_Integer)
+               if (IsA(&con->val, Integer))
                {
-                       con->val.val.ival = -con->val.val.ival;
+                       con->val.ival.val = -con->val.ival.val;
                        return n;
                }
-               if (con->val.type == T_Float)
+               if (IsA(&con->val, Float))
                {
-                       doNegateFloat(&con->val);
+                       doNegateFloat(&con->val.fval);
                        return n;
                }
        }
@@ -16906,17 +16902,16 @@ doNegate(Node *n, int location)
 }
 
 static void
-doNegateFloat(Value *v)
+doNegateFloat(Float *v)
 {
-       char   *oldval = v->val.str;
+       char   *oldval = v->val;
 
-       Assert(IsA(v, Float));
        if (*oldval == '+')
                oldval++;
        if (*oldval == '-')
-               v->val.str = oldval+1;  /* just strip the '-' */
+               v->val = oldval+1;      /* just strip the '-' */
        else
-               v->val.str = psprintf("-%s", oldval);
+               v->val = psprintf("-%s", oldval);
 }
 
 static Node *
index b3f151d33b5cca17b6f0cd437a2e965c495eb504..078029ba1f7ef2eded5376bb2b16f66e58d01a8f 100644 (file)
@@ -852,7 +852,7 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf)
                        {
                                foreach(lc2, ns_names)
                                {
-                                       Value      *ns_node = (Value *) lfirst(lc2);
+                                       String     *ns_node = lfirst_node(String, lc2);
 
                                        if (ns_node == NULL)
                                                continue;
@@ -1240,7 +1240,7 @@ transformFromClauseItem(ParseState *pstate, Node *n,
                        foreach(lx, l_colnames)
                        {
                                char       *l_colname = strVal(lfirst(lx));
-                               Value      *m_name = NULL;
+                               String     *m_name = NULL;
 
                                if (l_colname[0] == '\0')
                                        continue;       /* ignore dropped columns */
@@ -1785,7 +1785,7 @@ transformLimitClause(ParseState *pstate, Node *clause,
         * unadorned NULL that's not accepted back by the grammar.
         */
        if (exprKind == EXPR_KIND_LIMIT && limitOption == LIMIT_OPTION_WITH_TIES &&
-               IsA(clause, A_Const) && ((A_Const *) clause)->val.type == T_Null)
+               IsA(clause, A_Const) && castNode(A_Const, clause)->isnull)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE),
                                 errmsg("row count cannot be null in FETCH FIRST ... WITH TIES clause")));
@@ -1998,20 +1998,19 @@ findTargetlistEntrySQL92(ParseState *pstate, Node *node, List **tlist,
        }
        if (IsA(node, A_Const))
        {
-               Value      *val = &((A_Const *) node)->val;
-               int                     location = ((A_Const *) node)->location;
+               A_Const    *aconst = castNode(A_Const, node);
                int                     targetlist_pos = 0;
                int                     target_pos;
 
-               if (!IsA(val, Integer))
+               if (!IsA(&aconst->val, Integer))
                        ereport(ERROR,
                                        (errcode(ERRCODE_SYNTAX_ERROR),
                        /* translator: %s is name of a SQL construct, eg ORDER BY */
                                         errmsg("non-integer constant in %s",
                                                        ParseExprKindName(exprKind)),
-                                        parser_errposition(pstate, location)));
+                                        parser_errposition(pstate, aconst->location)));
 
-               target_pos = intVal(val);
+               target_pos = intVal(&aconst->val);
                foreach(tl, *tlist)
                {
                        TargetEntry *tle = (TargetEntry *) lfirst(tl);
@@ -2031,7 +2030,7 @@ findTargetlistEntrySQL92(ParseState *pstate, Node *node, List **tlist,
                /* translator: %s is name of a SQL construct, eg ORDER BY */
                                 errmsg("%s position %d is not in select list",
                                                ParseExprKindName(exprKind), target_pos),
-                                parser_errposition(pstate, location)));
+                                parser_errposition(pstate, aconst->location)));
        }
 
        /*
index f6ae96333af79f88caeaf496db628c8acf78447a..2f51caf76cfbaf4ff7b4510b38455d020d36002e 100644 (file)
@@ -393,7 +393,7 @@ analyzeCTE(ParseState *pstate, CommonTableExpr *cte)
 
                foreach(lc, cte->search_clause->search_col_list)
                {
-                       Value      *colname = lfirst(lc);
+                       String     *colname = lfirst_node(String, lc);
 
                        if (!list_member(cte->ctecolnames, colname))
                                ereport(ERROR,
@@ -428,7 +428,7 @@ analyzeCTE(ParseState *pstate, CommonTableExpr *cte)
 
                foreach(lc, cte->cycle_clause->cycle_col_list)
                {
-                       Value      *colname = lfirst(lc);
+                       String     *colname = lfirst_node(String, lc);
 
                        if (!list_member(cte->ctecolnames, colname))
                                ereport(ERROR,
index f928c3231138623c98cde98c6d6bc5271e8a985f..2d1a477154020cf165e481041c41b4432ccf29f3 100644 (file)
@@ -130,13 +130,8 @@ transformExprRecurse(ParseState *pstate, Node *expr)
                        break;
 
                case T_A_Const:
-                       {
-                               A_Const    *con = (A_Const *) expr;
-                               Value      *val = &con->val;
-
-                               result = (Node *) make_const(pstate, val, con->location);
-                               break;
-                       }
+                       result = (Node *) make_const(pstate, (A_Const *) expr);
+                       break;
 
                case T_A_Indirection:
                        result = transformIndirection(pstate, (A_Indirection *) expr);
@@ -855,7 +850,7 @@ exprIsNullConstant(Node *arg)
        {
                A_Const    *con = (A_Const *) arg;
 
-               if (con->val.type == T_Null)
+               if (con->isnull)
                        return true;
        }
        return false;
@@ -1626,7 +1621,7 @@ transformCaseExpr(ParseState *pstate, CaseExpr *c)
        {
                A_Const    *n = makeNode(A_Const);
 
-               n->val.type = T_Null;
+               n->isnull = true;
                n->location = -1;
                defresult = (Node *) n;
        }
index 17c900da31b35416b7864b8a96e43532bafe1d41..8cfe6f67c04922c179c34b7bd0a90d7bb88ab02c 100644 (file)
@@ -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;
 }
index 74659190447a243e5a73dc91f10ed988fbd78b20..c5c3f26ecf1364b061ddaffeddce0b22ab3756fe 100644 (file)
@@ -1140,7 +1140,7 @@ buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref)
        for (varattno = 0; varattno < maxattrs; varattno++)
        {
                Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
-               Value      *attrname;
+               String     *attrname;
 
                if (attr->attisdropped)
                {
@@ -1153,7 +1153,7 @@ buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref)
                else if (aliaslc)
                {
                        /* Use the next user-supplied alias */
-                       attrname = (Value *) lfirst(aliaslc);
+                       attrname = lfirst_node(String, aliaslc);
                        aliaslc = lnext(aliaslist, aliaslc);
                        alias->colnames = lappend(alias->colnames, attrname);
                }
@@ -3052,7 +3052,7 @@ expandNSItemVars(ParseNamespaceItem *nsitem,
        colindex = 0;
        foreach(lc, nsitem->p_names->colnames)
        {
-               Value      *colnameval = (Value *) lfirst(lc);
+               String     *colnameval = lfirst(lc);
                const char *colname = strVal(colnameval);
                ParseNamespaceColumn *nscol = nsitem->p_nscolumns + colindex;
 
index abe131ebebfc2d4f71d17dfc4d7f31900229c804..31b07ad5aed37538ed21fd0cba1d965081481d4f 100644 (file)
@@ -382,13 +382,17 @@ typenameTypeMod(ParseState *pstate, const TypeName *typeName, Type typ)
 
                        if (IsA(&ac->val, Integer))
                        {
-                               cstr = psprintf("%ld", (long) ac->val.val.ival);
+                               cstr = psprintf("%ld", (long) ac->val.ival.val);
                        }
-                       else if (IsA(&ac->val, Float) ||
-                                        IsA(&ac->val, String))
+                       else if (IsA(&ac->val, Float))
                        {
-                               /* we can just use the str field directly. */
-                               cstr = ac->val.val.str;
+                               /* we can just use the string representation directly. */
+                               cstr = ac->val.fval.val;
+                       }
+                       else if (IsA(&ac->val, String))
+                       {
+                               /* we can just use the string representation directly. */
+                               cstr = ac->val.sval.val;
                        }
                }
                else if (IsA(tm, ColumnRef))
index e5eefdbd43c1974434a2f3aed67ace3aff4a9651..1d3ee53244d291998fa10192530c410deb898466 100644 (file)
@@ -602,8 +602,8 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
                 */
                qstring = quote_qualified_identifier(snamespace, sname);
                snamenode = makeNode(A_Const);
-               snamenode->val.type = T_String;
-               snamenode->val.val.str = qstring;
+               snamenode->val.node.type = T_String;
+               snamenode->val.sval.val = qstring;
                snamenode->location = -1;
                castnode = makeNode(TypeCast);
                castnode->typeName = SystemTypeName("regclass");
index fd94e0c8818292ce7094cef4800c83bfa1703378..7be260663ece82c6e7b49c4ea0f40426924617a4 100644 (file)
@@ -324,7 +324,7 @@ oidparse(Node *node)
                         * constants by the lexer.  Accept these if they are valid OID
                         * strings.
                         */
-                       return oidin_subr(strVal(node), NULL);
+                       return oidin_subr(castNode(Float, node)->val, NULL);
                default:
                        elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
        }
index 1fb0b7b098419a87bbf658953e41dce621593af0..ccd2835c2223c151f979e2fe701824a5256ca0e5 100644 (file)
@@ -10514,7 +10514,7 @@ get_tablefunc(TableFunc *tf, deparse_context *context, bool showimplicit)
                forboth(lc1, tf->ns_uris, lc2, tf->ns_names)
                {
                        Node       *expr = (Node *) lfirst(lc1);
-                       Value      *ns_node = (Value *) lfirst(lc2);
+                       String     *ns_node = lfirst_node(String, lc2);
 
                        if (!first)
                                appendStringInfoString(buf, ", ");
index fd4ca83be17d5b80f3781cbe0d85b64d66b0c257..23236fa4c3d2c0f6b3c94e00c1afaa5f3b908dc6 100644 (file)
@@ -8301,7 +8301,7 @@ flatten_set_variable_args(const char *name, List *args)
                                break;
                        case T_Float:
                                /* represented as a string, so just copy it */
-                               appendStringInfoString(&buf, strVal(&con->val));
+                               appendStringInfoString(&buf, castNode(Float, &con->val)->val);
                                break;
                        case T_String:
                                val = strVal(&con->val);
@@ -8797,7 +8797,6 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
                                                         errmsg("SET LOCAL TRANSACTION SNAPSHOT is not implemented")));
 
                                WarnNoTransactionBlock(isTopLevel, "SET TRANSACTION");
-                               Assert(nodeTag(&con->val) == T_String);
                                ImportSnapshot(strVal(&con->val));
                        }
                        else
index 56d13ff0229ea294b7c8724d6641d09cef1cc4ae..a692eb7b098b6b505296b26f5aa2ff71e544fbe5 100644 (file)
@@ -291,12 +291,10 @@ typedef enum NodeTag
        /*
         * TAGS FOR VALUE NODES (value.h)
         */
-       T_Value,
        T_Integer,
        T_Float,
        T_String,
        T_BitString,
-       T_Null,
 
        /*
         * TAGS FOR LIST NODES (pg_list.h)
index 743e5aa4f34bbf72cd835e8fb66de7178854dc59..45e4f2a16e66a0171aca5b924a29fa4b3cc1defd 100644 (file)
@@ -218,7 +218,7 @@ typedef struct Query
 typedef struct TypeName
 {
        NodeTag         type;
-       List       *names;                      /* qualified name (list of Value strings) */
+       List       *names;                      /* qualified name (list of String nodes) */
        Oid                     typeOid;                /* type identified by OID */
        bool            setof;                  /* is a set? */
        bool            pct_type;               /* %TYPE specified? */
@@ -231,7 +231,7 @@ typedef struct TypeName
 /*
  * ColumnRef - specifies a reference to a column, or possibly a whole tuple
  *
- * The "fields" list must be nonempty.  It can contain string Value nodes
+ * The "fields" list must be nonempty.  It can contain String nodes
  * (representing names) and A_Star nodes (representing occurrence of a '*').
  * Currently, A_Star must appear only as the last list element --- the grammar
  * is responsible for enforcing this!
@@ -244,7 +244,7 @@ typedef struct TypeName
 typedef struct ColumnRef
 {
        NodeTag         type;
-       List       *fields;                     /* field names (Value strings) or A_Star */
+       List       *fields;                     /* field names (String nodes) or A_Star */
        int                     location;               /* token location, or -1 if unknown */
 } ColumnRef;
 
@@ -295,7 +295,19 @@ typedef struct A_Expr
 typedef struct A_Const
 {
        NodeTag         type;
-       Value           val;                    /* value (includes type info, see value.h) */
+       /*
+        * Value nodes are inline for performance.  You can treat 'val' as a node,
+        * as in IsA(&val, Integer).  'val' is not valid if isnull is true.
+        */
+       union ValUnion
+       {
+               Node            node;
+               Integer         ival;
+               Float           fval;
+               String          sval;
+               BitString       bsval;
+       }                       val;
+       bool            isnull;                 /* SQL NULL constant */
        int                     location;               /* token location, or -1 if unknown */
 } A_Const;
 
@@ -400,7 +412,7 @@ typedef struct A_Indices
  * A_Indirection - select a field and/or array element from an expression
  *
  * The indirection list can contain A_Indices nodes (representing
- * subscripting), string Value nodes (representing field selection --- the
+ * subscripting), String nodes (representing field selection --- the
  * string value is the name of the field to select), and A_Star nodes
  * (representing selection of all fields of a composite type).
  * For example, a complex selection operation like
@@ -744,7 +756,7 @@ typedef struct DefElem
        NodeTag         type;
        char       *defnamespace;       /* NULL if unqualified name */
        char       *defname;
-       Node       *arg;                        /* a (Value *) or a (TypeName *) */
+       Node       *arg;                        /* typically Integer, Float, String, or TypeName */
        DefElemAction defaction;        /* unspecified action, or SET/ADD/DROP */
        int                     location;               /* token location, or -1 if unknown */
 } DefElem;
@@ -2015,7 +2027,7 @@ typedef struct GrantStmt
        GrantTargetType targtype;       /* type of the grant target */
        ObjectType      objtype;                /* kind of object being operated on */
        List       *objects;            /* list of RangeVar nodes, ObjectWithArgs
-                                                                * nodes, or plain names (as Value strings) */
+                                                                * nodes, or plain names (as String values) */
        List       *privileges;         /* list of AccessPriv nodes */
        /* privileges == NIL denotes ALL PRIVILEGES */
        List       *grantees;           /* list of RoleSpec nodes */
@@ -2061,7 +2073,7 @@ typedef struct AccessPriv
 {
        NodeTag         type;
        char       *priv_name;          /* string name of privilege */
-       List       *cols;                       /* list of Value strings */
+       List       *cols;                       /* list of String */
 } AccessPriv;
 
 /* ----------------------
@@ -2070,7 +2082,7 @@ typedef struct AccessPriv
  * Note: because of the parsing ambiguity with the GRANT <privileges>
  * statement, granted_roles is a list of AccessPriv; the execution code
  * should complain if any column lists appear.  grantee_roles is a list
- * of role names, as Value strings.
+ * of role names, as String values.
  * ----------------------
  */
 typedef struct GrantRoleStmt
@@ -2531,7 +2543,7 @@ typedef struct CreateTrigStmt
        char       *trigname;           /* TRIGGER's name */
        RangeVar   *relation;           /* relation trigger is on */
        List       *funcname;           /* qual. name of function to call */
-       List       *args;                       /* list of (T_String) Values or NIL */
+       List       *args;                       /* list of String or NIL */
        bool            row;                    /* ROW/STATEMENT */
        /* timing uses the TRIGGER_TYPE bits defined in catalog/pg_trigger.h */
        int16           timing;                 /* BEFORE, AFTER, or INSTEAD */
@@ -2667,7 +2679,7 @@ typedef struct DefineStmt
        NodeTag         type;
        ObjectType      kind;                   /* aggregate, operator, type */
        bool            oldstyle;               /* hack to signal old CREATE AGG syntax */
-       List       *defnames;           /* qualified name (list of Value strings) */
+       List       *defnames;           /* qualified name (list of String) */
        List       *args;                       /* a list of TypeName (if needed) */
        List       *definition;         /* a list of DefElem */
        bool            if_not_exists;  /* just do nothing if it already exists? */
@@ -2681,7 +2693,7 @@ typedef struct DefineStmt
 typedef struct CreateDomainStmt
 {
        NodeTag         type;
-       List       *domainname;         /* qualified name (list of Value strings) */
+       List       *domainname;         /* qualified name (list of String) */
        TypeName   *typeName;           /* the base type */
        CollateClause *collClause;      /* untransformed COLLATE spec, if any */
        List       *constraints;        /* constraints (list of Constraint nodes) */
@@ -2694,7 +2706,7 @@ typedef struct CreateDomainStmt
 typedef struct CreateOpClassStmt
 {
        NodeTag         type;
-       List       *opclassname;        /* qualified name (list of Value strings) */
+       List       *opclassname;        /* qualified name (list of String) */
        List       *opfamilyname;       /* qualified name (ditto); NIL if omitted */
        char       *amname;                     /* name of index AM opclass is for */
        TypeName   *datatype;           /* datatype of indexed column */
@@ -2726,7 +2738,7 @@ typedef struct CreateOpClassItem
 typedef struct CreateOpFamilyStmt
 {
        NodeTag         type;
-       List       *opfamilyname;       /* qualified name (list of Value strings) */
+       List       *opfamilyname;       /* qualified name (list of String) */
        char       *amname;                     /* name of index AM opfamily is for */
 } CreateOpFamilyStmt;
 
@@ -2737,7 +2749,7 @@ typedef struct CreateOpFamilyStmt
 typedef struct AlterOpFamilyStmt
 {
        NodeTag         type;
-       List       *opfamilyname;       /* qualified name (list of Value strings) */
+       List       *opfamilyname;       /* qualified name (list of String) */
        char       *amname;                     /* name of index AM opfamily is for */
        bool            isDrop;                 /* ADD or DROP the items? */
        List       *items;                      /* List of CreateOpClassItem nodes */
@@ -2908,8 +2920,8 @@ typedef struct IndexStmt
 typedef struct CreateStatsStmt
 {
        NodeTag         type;
-       List       *defnames;           /* qualified name (list of Value strings) */
-       List       *stat_types;         /* stat types (list of Value strings) */
+       List       *defnames;           /* qualified name (list of String) */
+       List       *stat_types;         /* stat types (list of String) */
        List       *exprs;                      /* expressions to build statistics on */
        List       *relations;          /* rels to build stats on (list of RangeVar) */
        char       *stxcomment;         /* comment to apply to stats, or NULL */
@@ -2939,7 +2951,7 @@ typedef struct StatsElem
 typedef struct AlterStatsStmt
 {
        NodeTag         type;
-       List       *defnames;           /* qualified name (list of Value strings) */
+       List       *defnames;           /* qualified name (list of String) */
        int                     stxstattarget;  /* statistics target */
        bool            missing_ok;             /* skip error if statistics object is missing */
 } AlterStatsStmt;
@@ -3061,7 +3073,7 @@ typedef struct AlterObjectDependsStmt
        ObjectType      objectType;             /* OBJECT_FUNCTION, OBJECT_TRIGGER, etc */
        RangeVar   *relation;           /* in case a table is involved */
        Node       *object;                     /* name of the object */
-       Value      *extname;            /* extension name */
+       String     *extname;            /* extension name */
        bool            remove;                 /* set true to remove dep rather than add */
 } AlterObjectDependsStmt;
 
@@ -3207,8 +3219,8 @@ typedef struct CompositeTypeStmt
 typedef struct CreateEnumStmt
 {
        NodeTag         type;
-       List       *typeName;           /* qualified name (list of Value strings) */
-       List       *vals;                       /* enum values (list of Value strings) */
+       List       *typeName;           /* qualified name (list of String) */
+       List       *vals;                       /* enum values (list of String) */
 } CreateEnumStmt;
 
 /* ----------------------
@@ -3218,7 +3230,7 @@ typedef struct CreateEnumStmt
 typedef struct CreateRangeStmt
 {
        NodeTag         type;
-       List       *typeName;           /* qualified name (list of Value strings) */
+       List       *typeName;           /* qualified name (list of String) */
        List       *params;                     /* range parameters (list of DefElem) */
 } CreateRangeStmt;
 
@@ -3229,7 +3241,7 @@ typedef struct CreateRangeStmt
 typedef struct AlterEnumStmt
 {
        NodeTag         type;
-       List       *typeName;           /* qualified name (list of Value strings) */
+       List       *typeName;           /* qualified name (list of String) */
        char       *oldVal;                     /* old enum value's name, if renaming */
        char       *newVal;                     /* new enum value's name */
        char       *newValNeighbor; /* neighboring enum value, if specified */
@@ -3591,7 +3603,7 @@ typedef struct ReassignOwnedStmt
 typedef struct AlterTSDictionaryStmt
 {
        NodeTag         type;
-       List       *dictname;           /* qualified name (list of Value strings) */
+       List       *dictname;           /* qualified name (list of String) */
        List       *options;            /* List of DefElem nodes */
 } AlterTSDictionaryStmt;
 
@@ -3611,14 +3623,14 @@ typedef struct AlterTSConfigurationStmt
 {
        NodeTag         type;
        AlterTSConfigType kind;         /* ALTER_TSCONFIG_ADD_MAPPING, etc */
-       List       *cfgname;            /* qualified name (list of Value strings) */
+       List       *cfgname;            /* qualified name (list of String) */
 
        /*
         * dicts will be non-NIL if ADD/ALTER MAPPING was specified. If dicts is
         * NIL, but tokentype isn't, DROP MAPPING was specified.
         */
-       List       *tokentype;          /* list of Value strings */
-       List       *dicts;                      /* list of list of Value strings */
+       List       *tokentype;          /* list of String */
+       List       *dicts;                      /* list of list of String */
        bool            override;               /* if true - remove old variant */
        bool            replace;                /* if true - replace dictionary by another */
        bool            missing_ok;             /* for DROP - skip error if missing? */
index c04282f91fd417562d2b69f9a95bca04e8d03585..7b125904b4d9653feaabf6587cbb63a46942e6b6 100644 (file)
@@ -32,7 +32,7 @@
  *       specifies an alias for a range variable; the alias might also
  *       specify renaming of columns within the table.
  *
- * Note: colnames is a list of Value nodes (always strings).  In Alias structs
+ * Note: colnames is a list of String nodes.  In Alias structs
  * associated with RTEs, there may be entries corresponding to dropped
  * columns; these are normally empty strings ("").  See parsenodes.h for info.
  */
@@ -76,7 +76,7 @@ typedef struct RangeVar
 /*
  * TableFunc - node for a table function, such as XMLTABLE.
  *
- * Entries in the ns_names list are either string Value nodes containing
+ * Entries in the ns_names list are either String nodes containing
  * literal namespace names, or NULL pointers to represent DEFAULT.
  */
 typedef struct TableFunc
@@ -1227,7 +1227,7 @@ typedef struct XmlExpr
        XmlExprOp       op;                             /* xml function ID */
        char       *name;                       /* name in xml(NAME foo ...) syntaxes */
        List       *named_args;         /* non-XML expressions for xml_attributes */
-       List       *arg_names;          /* parallel list of Value strings */
+       List       *arg_names;          /* parallel list of String values */
        List       *args;                       /* list of expressions */
        XmlOptionType xmloption;        /* DOCUMENT or CONTENT */
        Oid                     type;                   /* target type/typmod for XMLSERIALIZE */
index b28928de54552fe7861a191957f938af83278208..8b71b510eb8f1ae1f113466a55df504165d19976 100644 (file)
@@ -1,7 +1,7 @@
 /*-------------------------------------------------------------------------
  *
  * value.h
- *       interface for Value nodes
+ *       interface for value nodes
  *
  *
  * Copyright (c) 2003-2021, PostgreSQL Global Development Group
 
 #include "nodes/nodes.h"
 
-/*----------------------
- *             Value node
+/*
+ * The node types Integer, Float, String, and BitString are used to represent
+ * literals in the lexer and are also used to pass constants around in the
+ * parser.  One difference between these node types and, say, a plain int or
+ * char * is that the nodes can be put into a List.
  *
- * The same Value struct is used for five node types: T_Integer,
- * T_Float, T_String, T_BitString, T_Null.
- *
- * Integral values are actually represented by a machine integer,
- * but both floats and strings are represented as strings.
- * Using T_Float as the node type simply indicates that
- * the contents of the string look like a valid numeric literal.
- *
- * (Before Postgres 7.0, we used a double to represent T_Float,
- * but that creates loss-of-precision problems when the value is
- * ultimately destined to be converted to NUMERIC.  Since Value nodes
- * are only used in the parsing process, not for runtime data, it's
- * better to use the more general representation.)
- *
- * Note that an integer-looking string will get lexed as T_Float if
- * the value is too large to fit in an 'int'.
+ * (There used to be a Value node, which encompassed all these different node types.  Hence the name of this file.)
+ */
+
+typedef struct Integer
+{
+       NodeTag         type;
+       int                     val;
+} Integer;
+
+/*
+ * Float is internally represented as string.  Using T_Float as the node type
+ * simply indicates that the contents of the string look like a valid numeric
+ * literal.  The value might end up being converted to NUMERIC, so we can't
+ * store it internally as a C double, since that could lose precision.  Since
+ * these nodes are generally only used in the parsing process, not for runtime
+ * data, it's better to use the more general representation.
  *
- * Nulls, of course, don't need the value part at all.
- *----------------------
+ * Note that an integer-looking string will get lexed as T_Float if the value
+ * is too large to fit in an 'int'.
  */
-typedef struct Value
+typedef struct Float
 {
-       NodeTag         type;                   /* tag appropriately (eg. T_String) */
-       union ValUnion
-       {
-               int                     ival;           /* machine integer */
-               char       *str;                /* string */
-       }                       val;
-} Value;
-
-#define intVal(v)              (((Value *)(v))->val.ival)
-#define floatVal(v)            atof(((Value *)(v))->val.str)
-#define strVal(v)              (((Value *)(v))->val.str)
-
-extern Value *makeInteger(int i);
-extern Value *makeFloat(char *numericStr);
-extern Value *makeString(char *str);
-extern Value *makeBitString(char *str);
+       NodeTag         type;
+       char       *val;
+} Float;
+
+typedef struct String
+{
+       NodeTag         type;
+       char       *val;
+} String;
+
+typedef struct BitString
+{
+       NodeTag         type;
+       char       *val;
+} BitString;
+
+#define intVal(v)              (castNode(Integer, v)->val)
+#define floatVal(v)            atof(castNode(Float, v)->val)
+#define strVal(v)              (castNode(String, v)->val)
+
+extern Integer *makeInteger(int i);
+extern Float *makeFloat(char *numericStr);
+extern String *makeString(char *str);
+extern BitString *makeBitString(char *str);
 
 #endif                                                 /* VALUE_H */
index 1500de2dd089550fc849493fef8a9a4ad9d918f6..ee179082cef659b79748bde6541873cbe8d20673 100644 (file)
@@ -333,7 +333,6 @@ extern SubscriptingRef *transformContainerSubscripts(ParseState *pstate,
                                                                                                         int32 containerTypMod,
                                                                                                         List *indirection,
                                                                                                         bool isAssignment);
-
-extern Const *make_const(ParseState *pstate, Value *value, int location);
+extern Const *make_const(ParseState *pstate, A_Const *aconst);
 
 #endif                                                 /* PARSE_NODE_H */