aboutsummaryrefslogtreecommitdiff
path: root/src/include/nodes/value.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/nodes/value.h')
-rw-r--r--src/include/nodes/value.h87
1 files changed, 49 insertions, 38 deletions
diff --git a/src/include/nodes/value.h b/src/include/nodes/value.h
index b28928de545..8b71b510eb8 100644
--- a/src/include/nodes/value.h
+++ b/src/include/nodes/value.h
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* value.h
- * interface for Value nodes
+ * interface for value nodes
*
*
* Copyright (c) 2003-2021, PostgreSQL Global Development Group
@@ -16,46 +16,57 @@
#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 */