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
{
/* 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
};
*/
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
};
/*
* 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).
*
* 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 *
};
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);
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:
*/
static ObjectAddress
get_object_address_unqualified(ObjectType objtype,
- Value *strval, bool missing_ok)
+ String *strval, bool missing_ok)
{
const char *name;
ObjectAddress address;
* 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)
{
/*
* 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));
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:
* strings.
*/
return DatumGetInt64(DirectFunctionCall1(int8in,
- CStringGetDatum(strVal(def->arg))));
+ CStringGetDatum(castNode(Float, def->arg)->val)));
default:
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
i = 0;
foreach(tn, tokennames)
{
- Value *val = (Value *) lfirst(tn);
+ String *val = lfirst_node(String, tn);
bool found = false;
int j;
i = 0;
foreach(c, stmt->tokentype)
{
- Value *val = (Value *) lfirst(c);
+ String *val = lfirst_node(String, c);
bool found = false;
ScanKeyInit(&skey[0],
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;
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/
{
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);
* 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;
}
* 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;
/*
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);
*/
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;
}
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;
/*
case T_Float:
case T_String:
case T_BitString:
- case T_Null:
case T_ParamRef:
case T_A_Const:
case T_A_Star:
}
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
{
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);
}
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, '{');
/*-------------------------------------------------------------------------
*
* 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;
}
*
* 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;
}
*
* 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;
}
*
* 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;
}
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);
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);
OnCommitAction oncommit;
List *list;
Node *node;
- Value *value;
ObjectType objtype;
TypeName *typnam;
FunctionParameter *fun_param;
%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
%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
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"),
;
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); }
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:
*
* 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
{
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 *
{
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 *
{
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 *
{
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 *
{
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;
}
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
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)
/* 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;
}
}
}
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 *
{
foreach(lc2, ns_names)
{
- Value *ns_node = (Value *) lfirst(lc2);
+ String *ns_node = lfirst_node(String, lc2);
if (ns_node == NULL)
continue;
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 */
* 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")));
}
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);
/* 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)));
}
/*
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,
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,
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);
{
A_Const *con = (A_Const *) arg;
- if (con->val.type == T_Null)
+ if (con->isnull)
return true;
}
return false;
{
A_Const *n = makeNode(A_Const);
- n->val.type = T_Null;
+ n->isnull = true;
n->location = -1;
defresult = (Node *) n;
}
/*
* 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.
* 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;
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);
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
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);
* 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 */
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);
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 */
}
val,
false,
typebyval);
- con->location = location;
+ con->location = aconst->location;
return con;
}
for (varattno = 0; varattno < maxattrs; varattno++)
{
Form_pg_attribute attr = TupleDescAttr(tupdesc, varattno);
- Value *attrname;
+ String *attrname;
if (attr->attisdropped)
{
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);
}
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;
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))
*/
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");
* 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));
}
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, ", ");
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);
errmsg("SET LOCAL TRANSACTION SNAPSHOT is not implemented")));
WarnNoTransactionBlock(isTopLevel, "SET TRANSACTION");
- Assert(nodeTag(&con->val) == T_String);
ImportSnapshot(strVal(&con->val));
}
else
/*
* 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)
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? */
/*
* 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!
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;
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;
* 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
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;
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 */
{
NodeTag type;
char *priv_name; /* string name of privilege */
- List *cols; /* list of Value strings */
+ List *cols; /* list of String */
} 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
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 */
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? */
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) */
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 */
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;
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 */
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 */
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;
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;
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;
/* ----------------------
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;
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 */
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;
{
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? */
* 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.
*/
/*
* 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
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 */
/*-------------------------------------------------------------------------
*
* 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 */
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 */