summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2009-04-04 21:12:31 +0000
committerTom Lane2009-04-04 21:12:31 +0000
commit3986136f3e7a1dc65cbf1f459c83be4f5704b7b1 (patch)
tree85dea8cfed89a803efa2475d9fa52a10c1ac8fba
parent572e20cff5e2dfbed105e6abb016431b4be473f1 (diff)
Remove the recently added node types ReloptElem and OptionDefElem in favor
of adding optional namespace and action fields to DefElem. Having three node types that do essentially the same thing bloats the code and leads to errors of confusion, such as in yesterday's bug report from Khee Chin.
-rw-r--r--src/backend/access/common/reloptions.c40
-rw-r--r--src/backend/commands/define.c94
-rw-r--r--src/backend/commands/foreigncmds.c69
-rw-r--r--src/backend/commands/sequence.c2
-rw-r--r--src/backend/commands/typecmds.c2
-rw-r--r--src/backend/commands/view.c2
-rw-r--r--src/backend/nodes/copyfuncs.c31
-rw-r--r--src/backend/nodes/equalfuncs.c27
-rw-r--r--src/backend/nodes/makefuncs.c32
-rw-r--r--src/backend/nodes/outfuncs.c15
-rw-r--r--src/backend/parser/gram.y114
-rw-r--r--src/backend/parser/parse_clause.c9
-rw-r--r--src/include/commands/defrem.h4
-rw-r--r--src/include/foreign/foreign.h8
-rw-r--r--src/include/nodes/makefuncs.h6
-rw-r--r--src/include/nodes/nodes.h2
-rw-r--r--src/include/nodes/parsenodes.h50
17 files changed, 191 insertions, 316 deletions
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index ae14e1193b..4b0bfb9f01 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -483,7 +483,7 @@ add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val,
}
/*
- * Transform a relation options list (list of ReloptElem) into the text array
+ * Transform a relation options list (list of DefElem) into the text array
* format that is kept in pg_class.reloptions, including only those options
* that are in the passed namespace. The output values do not include the
* namespace.
@@ -542,23 +542,23 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace,
/* Search for a match in defList */
foreach(cell, defList)
{
- ReloptElem *def = lfirst(cell);
+ DefElem *def = (DefElem *) lfirst(cell);
int kw_len;
/* ignore if not in the same namespace */
if (namspace == NULL)
{
- if (def->nmspc != NULL)
+ if (def->defnamespace != NULL)
continue;
}
- else if (def->nmspc == NULL)
+ else if (def->defnamespace == NULL)
continue;
- else if (pg_strcasecmp(def->nmspc, namspace) != 0)
+ else if (pg_strcasecmp(def->defnamespace, namspace) != 0)
continue;
- kw_len = strlen(def->optname);
+ kw_len = strlen(def->defname);
if (text_len > kw_len && text_str[kw_len] == '=' &&
- pg_strncasecmp(text_str, def->optname, kw_len) == 0)
+ pg_strncasecmp(text_str, def->defname, kw_len) == 0)
break;
}
if (!cell)
@@ -578,8 +578,7 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace,
*/
foreach(cell, defList)
{
- ReloptElem *def = lfirst(cell);
-
+ DefElem *def = (DefElem *) lfirst(cell);
if (isReset)
{
@@ -598,7 +597,7 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace,
* Error out if the namespace is not valid. A NULL namespace
* is always valid.
*/
- if (def->nmspc != NULL)
+ if (def->defnamespace != NULL)
{
bool valid = false;
int i;
@@ -607,7 +606,8 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace,
{
for (i = 0; validnsps[i]; i++)
{
- if (pg_strcasecmp(def->nmspc, validnsps[i]) == 0)
+ if (pg_strcasecmp(def->defnamespace,
+ validnsps[i]) == 0)
{
valid = true;
break;
@@ -619,37 +619,37 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace,
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized parameter namespace \"%s\"",
- def->nmspc)));
+ def->defnamespace)));
}
- if (ignoreOids && pg_strcasecmp(def->optname, "oids") == 0)
+ if (ignoreOids && pg_strcasecmp(def->defname, "oids") == 0)
continue;
/* ignore if not in the same namespace */
if (namspace == NULL)
{
- if (def->nmspc != NULL)
+ if (def->defnamespace != NULL)
continue;
}
- else if (def->nmspc == NULL)
+ else if (def->defnamespace == NULL)
continue;
- else if (pg_strcasecmp(def->nmspc, namspace) != 0)
+ else if (pg_strcasecmp(def->defnamespace, namspace) != 0)
continue;
/*
- * Flatten the ReloptElem into a text string like "name=arg". If we
+ * Flatten the DefElem into a text string like "name=arg". If we
* have just "name", assume "name=true" is meant. Note: the
* namespace is not output.
*/
if (def->arg != NULL)
- value = reloptGetString(def);
+ value = defGetString(def);
else
value = "true";
- len = VARHDRSZ + strlen(def->optname) + 1 + strlen(value);
+ len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
/* +1 leaves room for sprintf's trailing null */
t = (text *) palloc(len + 1);
SET_VARSIZE(t, len);
- sprintf(VARDATA(t), "%s=%s", def->optname, value);
+ sprintf(VARDATA(t), "%s=%s", def->defname, value);
astate = accumArrayResult(astate, PointerGetDatum(t),
false, TEXTOID,
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index a5d2d55bda..2d6343aa19 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -55,20 +55,24 @@ case_translate_language_name(const char *input)
}
-static char *
-nodeGetString(Node *value, char *name)
+/*
+ * Extract a string value (otherwise uninterpreted) from a DefElem.
+ */
+char *
+defGetString(DefElem *def)
{
- if (value == NULL)
+ if (def->arg == NULL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("%s requires a parameter", name)));
- switch (nodeTag(value))
+ errmsg("%s requires a parameter",
+ def->defname)));
+ switch (nodeTag(def->arg))
{
case T_Integer:
{
char *str = palloc(32);
- snprintf(str, 32, "%ld", (long) intVal(value));
+ snprintf(str, 32, "%ld", (long) intVal(def->arg));
return str;
}
case T_Float:
@@ -77,29 +81,20 @@ nodeGetString(Node *value, char *name)
* T_Float values are kept in string form, so this type cheat
* works (and doesn't risk losing precision)
*/
- return strVal(value);
+ return strVal(def->arg);
case T_String:
- return strVal(value);
+ return strVal(def->arg);
case T_TypeName:
- return TypeNameToString((TypeName *) value);
+ return TypeNameToString((TypeName *) def->arg);
case T_List:
- return NameListToString((List *) value);
+ return NameListToString((List *) def->arg);
default:
- elog(ERROR, "unrecognized node type: %d", (int) nodeTag(value));
+ elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
}
return NULL; /* keep compiler quiet */
}
/*
- * Extract a string value (otherwise uninterpreted) from a DefElem.
- */
-char *
-defGetString(DefElem *def)
-{
- return nodeGetString(def->arg, def->defname);
-}
-
-/*
* Extract a numeric value (actually double) from a DefElem.
*/
double
@@ -125,22 +120,25 @@ defGetNumeric(DefElem *def)
return 0; /* keep compiler quiet */
}
-static bool
-nodeGetBoolean(Node *value, char *name)
+/*
+ * Extract a boolean value from a DefElem.
+ */
+bool
+defGetBoolean(DefElem *def)
{
/*
* If no parameter given, assume "true" is meant.
*/
- if (value == NULL)
+ if (def->arg == NULL)
return true;
/*
* Allow 0, 1, "true", "false"
*/
- switch (nodeTag(value))
+ switch (nodeTag(def->arg))
{
case T_Integer:
- switch (intVal(value))
+ switch (intVal(def->arg))
{
case 0:
return false;
@@ -153,7 +151,7 @@ nodeGetBoolean(Node *value, char *name)
break;
default:
{
- char *sval = nodeGetString(value, name);
+ char *sval = defGetString(def);
if (pg_strcasecmp(sval, "true") == 0)
return true;
@@ -165,20 +163,12 @@ nodeGetBoolean(Node *value, char *name)
}
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("%s requires a Boolean value", name)));
+ errmsg("%s requires a Boolean value",
+ def->defname)));
return false; /* keep compiler quiet */
}
/*
- * Extract a boolean value from a DefElem.
- */
-bool
-defGetBoolean(DefElem *def)
-{
- return nodeGetBoolean(def->arg, def->defname);
-}
-
-/*
* Extract an int64 value from a DefElem.
*/
int64
@@ -315,35 +305,11 @@ defGetTypeLength(DefElem *def)
return 0; /* keep compiler quiet */
}
-
/*
- * Extract a string value (otherwise uninterpreted) from a ReloptElem.
+ * Create a DefElem setting "oids" to the specified value.
*/
-char *
-reloptGetString(ReloptElem *relopt)
+DefElem *
+defWithOids(bool value)
{
- return nodeGetString(relopt->arg, relopt->optname);
-}
-
-/*
- * Extract a boolean value from a ReloptElem.
- */
-bool
-reloptGetBoolean(ReloptElem *relopt)
-{
- return nodeGetBoolean(relopt->arg, relopt->optname);
-}
-
-/*
- * Create a ReloptElem setting "oids" to the specified value.
- */
-ReloptElem *
-reloptWithOids(bool value)
-{
- ReloptElem *f = makeNode(ReloptElem);
-
- f->optname = "oids";
- f->nmspc = NULL;
- f->arg = (Node *) makeInteger(value);
- return f;
+ return makeDefElem("oids", (Node *) makeInteger(value));
}
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 84b7ffac4b..52abcc2572 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -76,33 +76,31 @@ optionListToArray(List *options)
/*
- * Transform the list of OptionDefElem into list of generic options.
- * The result is converted to array of text suitable for storing in
- * options.
+ * Transform a list of DefElem into text array format. This is substantially
+ * the same thing as optionListToArray(), except we recognize SET/ADD/DROP
+ * actions for modifying an existing list of options, which is passed in
+ * Datum form as oldOptions. Also, if fdwvalidator isn't InvalidOid
+ * it specifies a validator function to call on the result.
*
* Returns the array in the form of a Datum, or PointerGetDatum(NULL)
* if the list is empty.
*
- * This is used by CREATE/ALTER of FOREIGN DATA WRAPPER/SERVER/USER
- * MAPPING. In the ALTER cases, oldOptions is the current text array
- * of options.
+ * This is used by CREATE/ALTER of FOREIGN DATA WRAPPER/SERVER/USER MAPPING.
*/
static Datum
transformGenericOptions(Datum oldOptions,
- List *optionDefList,
- GenericOptionFlags flags,
- ForeignDataWrapper *fdw,
+ List *options,
Oid fdwvalidator)
{
List *resultOptions = untransformRelOptions(oldOptions);
ListCell *optcell;
Datum result;
- foreach(optcell, optionDefList)
+ foreach(optcell, options)
{
- OptionDefElem *od = lfirst(optcell);
- ListCell *cell;
- ListCell *prev = NULL;
+ DefElem *od = lfirst(optcell);
+ ListCell *cell;
+ ListCell *prev = NULL;
/*
* Find the element in resultOptions. We need this for
@@ -112,7 +110,7 @@ transformGenericOptions(Datum oldOptions,
{
DefElem *def = lfirst(cell);
- if (strcmp(def->defname, od->def->defname) == 0)
+ if (strcmp(def->defname, od->defname) == 0)
break;
else
prev = cell;
@@ -121,41 +119,42 @@ transformGenericOptions(Datum oldOptions,
/*
* It is possible to perform multiple SET/DROP actions on the
* same option. The standard permits this, as long as the
- * options to be added are unique.
+ * options to be added are unique. Note that an unspecified
+ * action is taken to be ADD.
*/
-
- switch (od->alter_op)
+ switch (od->defaction)
{
- case ALTER_OPT_DROP:
+ case DEFELEM_DROP:
if (!cell)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("option \"%s\" not found",
- od->def->defname)));
+ od->defname)));
resultOptions = list_delete_cell(resultOptions, cell, prev);
break;
- case ALTER_OPT_SET:
+ case DEFELEM_SET:
if (!cell)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("option \"%s\" not found",
- od->def->defname)));
- lfirst(cell) = od->def;
+ od->defname)));
+ lfirst(cell) = od;
break;
- case ALTER_OPT_ADD:
+ case DEFELEM_ADD:
+ case DEFELEM_UNSPEC:
if (cell)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("option \"%s\" provided more than once",
- od->def->defname)));
- resultOptions = lappend(resultOptions, od->def);
+ od->defname)));
+ resultOptions = lappend(resultOptions, od);
break;
default:
elog(ERROR, "unrecognized action %d on option \"%s\"",
- od->alter_op, od->def->defname);
+ (int) od->defaction, od->defname);
break;
}
}
@@ -163,7 +162,7 @@ transformGenericOptions(Datum oldOptions,
result = optionListToArray(resultOptions);
if (fdwvalidator)
- OidFunctionCall2(fdwvalidator, result, 0);
+ OidFunctionCall2(fdwvalidator, result, (Datum) 0);
return result;
}
@@ -386,7 +385,6 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
nulls[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
fdwoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options,
- FdwOpt, NULL,
fdwvalidator);
if (PointerIsValid(DatumGetPointer(fdwoptions)))
@@ -504,8 +502,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
datum = PointerGetDatum(NULL);
/* Transform the options */
- datum = transformGenericOptions(datum, stmt->options, FdwOpt,
- NULL, fdwvalidator);
+ datum = transformGenericOptions(datum, stmt->options, fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = datum;
@@ -672,7 +669,6 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
/* Add server options */
srvoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options,
- ServerOpt, fdw,
fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(srvoptions)))
@@ -770,8 +766,8 @@ AlterForeignServer(AlterForeignServerStmt *stmt)
datum = PointerGetDatum(NULL);
/* Prepare the options array */
- datum = transformGenericOptions(datum, stmt->options, ServerOpt,
- fdw, fdw->fdwvalidator);
+ datum = transformGenericOptions(datum, stmt->options,
+ fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_foreign_server_srvoptions - 1] = datum;
@@ -942,8 +938,7 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
/* Add user options */
useoptions = transformGenericOptions(PointerGetDatum(NULL), stmt->options,
- UserMappingOpt,
- fdw, fdw->fdwvalidator);
+ fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(useoptions)))
values[Anum_pg_user_mapping_umoptions - 1] = useoptions;
@@ -1037,8 +1032,8 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
datum = PointerGetDatum(NULL);
/* Prepare the options array */
- datum = transformGenericOptions(datum, stmt->options, UserMappingOpt,
- fdw, fdw->fdwvalidator);
+ datum = transformGenericOptions(datum, stmt->options,
+ fdw->fdwvalidator);
if (PointerIsValid(DatumGetPointer(datum)))
repl_val[Anum_pg_user_mapping_umoptions - 1] = datum;
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 2f178054f2..46d7683377 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -198,7 +198,7 @@ DefineSequence(CreateSeqStmt *seq)
stmt->relation = seq->sequence;
stmt->inhRelations = NIL;
stmt->constraints = NIL;
- stmt->options = list_make1(reloptWithOids(false));
+ stmt->options = list_make1(defWithOids(false));
stmt->oncommit = ONCOMMIT_NOOP;
stmt->tablespacename = NULL;
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 98e01e455b..7d4c363c47 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1496,7 +1496,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
createStmt->tableElts = coldeflist;
createStmt->inhRelations = NIL;
createStmt->constraints = NIL;
- createStmt->options = list_make1(reloptWithOids(false));
+ createStmt->options = list_make1(defWithOids(false));
createStmt->oncommit = ONCOMMIT_NOOP;
createStmt->tablespacename = NULL;
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index 60dcfb3c77..ac70facce7 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -229,7 +229,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
createStmt->tableElts = attrList;
createStmt->inhRelations = NIL;
createStmt->constraints = NIL;
- createStmt->options = list_make1(reloptWithOids(false));
+ createStmt->options = list_make1(defWithOids(false));
createStmt->oncommit = ONCOMMIT_NOOP;
createStmt->tablespacename = NULL;
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 01e5fc219b..3a51aca78e 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2098,31 +2098,10 @@ _copyDefElem(DefElem *from)
{
DefElem *newnode = makeNode(DefElem);
+ COPY_STRING_FIELD(defnamespace);
COPY_STRING_FIELD(defname);
COPY_NODE_FIELD(arg);
-
- return newnode;
-}
-
-static OptionDefElem *
-_copyOptionDefElem(OptionDefElem *from)
-{
- OptionDefElem *newnode = makeNode(OptionDefElem);
-
- COPY_SCALAR_FIELD(alter_op);
- COPY_NODE_FIELD(def);
-
- return newnode;
-}
-
-static ReloptElem *
-_copyReloptElem(ReloptElem *from)
-{
- ReloptElem *newnode = makeNode(ReloptElem);
-
- COPY_STRING_FIELD(optname);
- COPY_STRING_FIELD(nmspc);
- COPY_NODE_FIELD(arg);
+ COPY_SCALAR_FIELD(defaction);
return newnode;
}
@@ -4076,12 +4055,6 @@ copyObject(void *from)
case T_DefElem:
retval = _copyDefElem(from);
break;
- case T_OptionDefElem:
- retval = _copyOptionDefElem(from);
- break;
- case T_ReloptElem:
- retval = _copyReloptElem(from);
- break;
case T_LockingClause:
retval = _copyLockingClause(from);
break;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 3e0487beef..537bf68e19 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -2074,27 +2074,10 @@ _equalConstraint(Constraint *a, Constraint *b)
static bool
_equalDefElem(DefElem *a, DefElem *b)
{
+ COMPARE_STRING_FIELD(defnamespace);
COMPARE_STRING_FIELD(defname);
COMPARE_NODE_FIELD(arg);
-
- return true;
-}
-
-static bool
-_equalOptionDefElem(OptionDefElem *a, OptionDefElem *b)
-{
- COMPARE_SCALAR_FIELD(alter_op);
- COMPARE_NODE_FIELD(def);
-
- return true;
-}
-
-static bool
-_equalReloptElem(ReloptElem *a, ReloptElem *b)
-{
- COMPARE_STRING_FIELD(nmspc);
- COMPARE_STRING_FIELD(optname);
- COMPARE_NODE_FIELD(arg);
+ COMPARE_SCALAR_FIELD(defaction);
return true;
}
@@ -2850,12 +2833,6 @@ equal(void *a, void *b)
case T_DefElem:
retval = _equalDefElem(a, b);
break;
- case T_OptionDefElem:
- retval = _equalOptionDefElem(a, b);
- break;
- case T_ReloptElem:
- retval = _equalReloptElem(a, b);
- break;
case T_LockingClause:
retval = _equalLockingClause(a, b);
break;
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 440577048b..6e3cc13d3c 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -351,37 +351,37 @@ makeFuncExpr(Oid funcid, Oid rettype, List *args, CoercionForm fformat)
/*
* makeDefElem -
* build a DefElem node
+ *
+ * This is sufficient for the "typical" case with an unqualified option name
+ * and no special action.
*/
DefElem *
makeDefElem(char *name, Node *arg)
{
DefElem *res = makeNode(DefElem);
+ res->defnamespace = NULL;
res->defname = name;
res->arg = arg;
+ res->defaction = DEFELEM_UNSPEC;
+
return res;
}
/*
- * makeOptionDefElem -
- * build an OptionDefElem node
+ * makeDefElemExtended -
+ * build a DefElem node with all fields available to be specified
*/
-OptionDefElem *
-makeOptionDefElem(int op, DefElem *def)
-{
- OptionDefElem *res = makeNode(OptionDefElem);
- res->alter_op = op;
- res->def = def;
- return res;
-}
-
-ReloptElem *
-makeReloptElem(char *name, char *nmspc, Node *arg)
+DefElem *
+makeDefElemExtended(char *namespace, char *name, Node *arg,
+ DefElemAction defaction)
{
- ReloptElem *res = makeNode(ReloptElem);
+ DefElem *res = makeNode(DefElem);
- res->optname = name;
- res->nmspc = nmspc;
+ res->defnamespace = namespace;
+ res->defname = name;
res->arg = arg;
+ res->defaction = defaction;
+
return res;
}
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 68a44339da..236ae60c8a 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1797,18 +1797,10 @@ _outDefElem(StringInfo str, DefElem *node)
{
WRITE_NODE_TYPE("DEFELEM");
+ WRITE_STRING_FIELD(defnamespace);
WRITE_STRING_FIELD(defname);
WRITE_NODE_FIELD(arg);
-}
-
-static void
-_outReloptElem(StringInfo str, ReloptElem *node)
-{
- WRITE_NODE_TYPE("RELOPTELEM");
-
- WRITE_STRING_FIELD(nmspc);
- WRITE_STRING_FIELD(optname);
- WRITE_NODE_FIELD(arg);
+ WRITE_ENUM_FIELD(defaction, DefElemAction);
}
static void
@@ -2774,9 +2766,6 @@ _outNode(StringInfo str, void *obj)
case T_DefElem:
_outDefElem(str, obj);
break;
- case T_ReloptElem:
- _outReloptElem(str, obj);
- break;
case T_LockingClause:
_outLockingClause(str, obj);
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 7c45f68e23..e1de04e761 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -163,8 +163,6 @@ static TypeName *TableFuncTypeName(List *columns);
FunctionParameterMode fun_param_mode;
FuncWithArgs *funwithargs;
DefElem *defelt;
- OptionDefElem *optdef;
- ReloptElem *reloptel;
SortBy *sortby;
WindowDef *windef;
JoinExpr *jexpr;
@@ -343,8 +341,7 @@ static TypeName *TableFuncTypeName(List *columns);
%type <node> TableElement ConstraintElem TableFuncElement
%type <node> columnDef
-%type <defelt> def_elem old_aggr_elem
-%type <reloptel> reloption_elem
+%type <defelt> def_elem reloption_elem old_aggr_elem
%type <node> def_arg columnElem where_clause where_or_current_clause
a_expr b_expr c_expr func_expr AexprConst indirection_el
columnref in_expr having_clause func_table array_expr
@@ -366,8 +363,7 @@ static TypeName *TableFuncTypeName(List *columns);
%type <str> generic_option_name
%type <node> generic_option_arg
-%type <defelt> generic_option_elem
-%type <optdef> alter_generic_option_elem
+%type <defelt> generic_option_elem alter_generic_option_elem
%type <list> generic_option_list alter_generic_option_list
%type <typnam> Typename SimpleTypename ConstTypename
@@ -1837,22 +1833,24 @@ reloption_list:
| reloption_list ',' reloption_elem { $$ = lappend($1, $3); }
;
+/* This should match def_elem and also allow qualified names */
reloption_elem:
ColLabel '=' def_arg
{
- $$ = makeReloptElem($1, NULL, (Node *) $3);
+ $$ = makeDefElem($1, (Node *) $3);
}
| ColLabel
{
- $$ = makeReloptElem($1, NULL, NULL);
+ $$ = makeDefElem($1, NULL);
}
| ColLabel '.' ColLabel '=' def_arg
{
- $$ = makeReloptElem($3, $1, (Node *) $5);
+ $$ = makeDefElemExtended($1, $3, (Node *) $5,
+ DEFELEM_UNSPEC);
}
| ColLabel '.' ColLabel
{
- $$ = makeReloptElem($3, $1, NULL);
+ $$ = makeDefElemExtended($1, $3, NULL, DEFELEM_UNSPEC);
}
;
@@ -2482,8 +2480,8 @@ OptInherit: INHERITS '(' qualified_name_list ')' { $$ = $3; }
/* WITH (options) is preferred, WITH OIDS and WITHOUT OIDS are legacy forms */
OptWith:
WITH reloptions { $$ = $2; }
- | WITH OIDS { $$ = list_make1(reloptWithOids(true)); }
- | WITHOUT OIDS { $$ = list_make1(reloptWithOids(false)); }
+ | WITH OIDS { $$ = list_make1(defWithOids(true)); }
+ | WITHOUT OIDS { $$ = list_make1(defWithOids(false)); }
| /*EMPTY*/ { $$ = NIL; }
;
@@ -2887,70 +2885,72 @@ AlterFdwStmt: ALTER FOREIGN DATA_P WRAPPER name validator_clause alter_generic_o
/* Options definition for CREATE FDW, SERVER and USER MAPPING */
create_generic_options:
- OPTIONS '(' generic_option_list ')' { $$ = $3; }
- | /*EMPTY*/ { $$ = NIL; }
+ OPTIONS '(' generic_option_list ')' { $$ = $3; }
+ | /*EMPTY*/ { $$ = NIL; }
;
-generic_option_list: generic_option_elem
- {
- $$ = list_make1(makeOptionDefElem(ALTER_OPT_ADD, $1));
- }
- | generic_option_list ',' generic_option_elem
- {
- $$ = lappend($1, makeOptionDefElem(ALTER_OPT_ADD, $3));
- }
+generic_option_list:
+ generic_option_elem
+ {
+ $$ = list_make1($1);
+ }
+ | generic_option_list ',' generic_option_elem
+ {
+ $$ = lappend($1, $3);
+ }
;
/* Options definition for ALTER FDW, SERVER and USER MAPPING */
alter_generic_options:
- OPTIONS '(' alter_generic_option_list ')' { $$ = $3; }
+ OPTIONS '(' alter_generic_option_list ')' { $$ = $3; }
;
alter_generic_option_list:
- alter_generic_option_elem
- {
- $$ = list_make1($1);
- }
- | generic_option_elem
- {
- $$ = list_make1(makeOptionDefElem(ALTER_OPT_ADD, $1));
- }
- | alter_generic_option_list ',' alter_generic_option_elem
- {
- $$ = lappend($1, $3);
- }
- | alter_generic_option_list ',' generic_option_elem
- {
- $$ = lappend($1, makeOptionDefElem(ALTER_OPT_ADD, $3));
- }
+ alter_generic_option_elem
+ {
+ $$ = list_make1($1);
+ }
+ | alter_generic_option_list ',' alter_generic_option_elem
+ {
+ $$ = lappend($1, $3);
+ }
;
alter_generic_option_elem:
- ADD_P generic_option_elem
- {
- $$ = makeOptionDefElem(ALTER_OPT_ADD, $2);
- }
- | SET generic_option_elem
- {
- $$ = makeOptionDefElem(ALTER_OPT_SET, $2);
- }
- | DROP generic_option_name
- {
- $$ = makeOptionDefElem(ALTER_OPT_DROP,
- makeDefElem($2, NULL));
- }
+ generic_option_elem
+ {
+ $$ = $1;
+ }
+ | SET generic_option_elem
+ {
+ $$ = $2;
+ $$->defaction = DEFELEM_SET;
+ }
+ | ADD_P generic_option_elem
+ {
+ $$ = $2;
+ $$->defaction = DEFELEM_ADD;
+ }
+ | DROP generic_option_name
+ {
+ $$ = makeDefElemExtended(NULL, $2, NULL, DEFELEM_DROP);
+ }
;
generic_option_elem:
- generic_option_name generic_option_arg { $$ = makeDefElem($1, $2); }
+ generic_option_name generic_option_arg
+ {
+ $$ = makeDefElem($1, $2);
+ }
;
generic_option_name:
- attr_name { $$ = $1; }
+ ColLabel { $$ = $1; }
;
+/* We could use def_arg here, but the spec only requires string literals */
generic_option_arg:
- Sconst { $$ = (Node *)makeString($1); }
+ Sconst { $$ = (Node *) makeString($1); }
;
/*****************************************************************************
@@ -3504,9 +3504,9 @@ def_list: def_elem { $$ = list_make1($1); }
| def_list ',' def_elem { $$ = lappend($1, $3); }
;
-def_elem: ColLabel '=' def_arg
+def_elem: ColLabel '=' def_arg
{
- $$ = makeDefElem($1, (Node *)$3);
+ $$ = makeDefElem($1, (Node *) $3);
}
| ColLabel
{
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index ef548a7aff..f566d4c7a3 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -233,7 +233,7 @@ interpretInhOption(InhOption inhOpt)
}
/*
- * Given a relation-options list (of ReloptElems), return true iff the specified
+ * Given a relation-options list (of DefElems), return true iff the specified
* table/result set should be created with OIDs. This needs to be done after
* parsing the query string because the return value can depend upon the
* default_with_oids GUC var.
@@ -246,10 +246,11 @@ interpretOidsOption(List *defList)
/* Scan list to see if OIDS was included */
foreach(cell, defList)
{
- ReloptElem *def = (ReloptElem *) lfirst(cell);
+ DefElem *def = (DefElem *) lfirst(cell);
- if (pg_strcasecmp(def->optname, "oids") == 0)
- return reloptGetBoolean(def);
+ if (def->defnamespace == NULL &&
+ pg_strcasecmp(def->defname, "oids") == 0)
+ return defGetBoolean(def);
}
/* OIDS option was not specified, so use default. */
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 64af22cbd6..4356492c97 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -145,8 +145,6 @@ extern int64 defGetInt64(DefElem *def);
extern List *defGetQualifiedName(DefElem *def);
extern TypeName *defGetTypeName(DefElem *def);
extern int defGetTypeLength(DefElem *def);
-extern char *reloptGetString(ReloptElem *relopt);
-extern bool reloptGetBoolean(ReloptElem *relopt);
-extern ReloptElem *reloptWithOids(bool value);
+extern DefElem *defWithOids(bool value);
#endif /* DEFREM_H */
diff --git a/src/include/foreign/foreign.h b/src/include/foreign/foreign.h
index e068e682a3..fd2773140e 100644
--- a/src/include/foreign/foreign.h
+++ b/src/include/foreign/foreign.h
@@ -14,7 +14,6 @@
#define FOREIGN_H
#include "nodes/parsenodes.h"
-#include "nodes/pg_list.h"
/* Helper for obtaining username for user mapping */
@@ -27,10 +26,9 @@
* NB! Thes are treated as flags, so use only powers of two here.
*/
typedef enum {
- InvalidOpt = 0,
ServerOpt = 1, /* options applicable to SERVER */
UserMappingOpt = 2, /* options for USER MAPPING */
- FdwOpt = 4, /* options for FOREIGN DATA WRAPPER */
+ FdwOpt = 4 /* options for FOREIGN DATA WRAPPER */
} GenericOptionFlags;
typedef struct ForeignDataWrapper
@@ -70,8 +68,4 @@ extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *name,
bool missing_ok);
extern Oid GetForeignDataWrapperOidByName(const char *name, bool missing_ok);
-/* Foreign data wrapper interface functions */
-extern void _pg_validateOptionList(ForeignDataWrapper *fdw,
- GenericOptionFlags flags, List *options);
-
#endif /* FOREIGN_H */
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index cd7bedfb42..3a2a7f4010 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -66,9 +66,7 @@ extern FuncExpr *makeFuncExpr(Oid funcid, Oid rettype,
List *args, CoercionForm fformat);
extern DefElem *makeDefElem(char *name, Node *arg);
-
-extern OptionDefElem *makeOptionDefElem(int op, DefElem *def);
-
-extern ReloptElem *makeReloptElem(char *name, char *namspc, Node *arg);
+extern DefElem *makeDefElemExtended(char *namespace, char *name, Node *arg,
+ DefElemAction defaction);
#endif /* MAKEFUNC_H */
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 2620a80407..30ee53dc9b 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -361,8 +361,6 @@ typedef enum NodeTag
T_IndexElem,
T_Constraint,
T_DefElem,
- T_OptionDefElem,
- T_ReloptElem,
T_RangeTblEntry,
T_SortGroupClause,
T_WindowClause,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 3fc17b5a70..6d3265f8b0 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -50,14 +50,6 @@ typedef enum SortByNulls
SORTBY_NULLS_LAST
} SortByNulls;
-/* Alter operations for generic options */
-typedef enum AlterOptionOp
-{
- ALTER_OPT_DROP = -1,
- ALTER_OPT_SET,
- ALTER_OPT_ADD
-} AlterOptionOp;
-
/*
* Grantable rights are encoded so that we can OR them together in a bitmask.
* The present representation of AclItem limits us to 16 distinct rights,
@@ -511,39 +503,33 @@ typedef struct IndexElem
} IndexElem;
/*
- * DefElem -
- * a definition (used in definition lists in the form of defname = arg)
+ * DefElem - a generic "name = value" option definition
+ *
+ * In some contexts the name can be qualified. Also, certain SQL commands
+ * allow a SET/ADD/DROP action to be attached to option settings, so it's
+ * convenient to carry a field for that too. (Note: currently, it is our
+ * practice that the grammar allows namespace and action only in statements
+ * where they are relevant; C code can just ignore those fields in other
+ * statements.)
*/
+typedef enum DefElemAction
+{
+ DEFELEM_UNSPEC, /* no action given */
+ DEFELEM_SET,
+ DEFELEM_ADD,
+ DEFELEM_DROP
+} DefElemAction;
+
typedef struct DefElem
{
NodeTag type;
+ char *defnamespace; /* NULL if unqualified name */
char *defname;
Node *arg; /* a (Value *) or a (TypeName *) */
+ DefElemAction defaction; /* unspecified action, or SET/ADD/DROP */
} DefElem;
/*
- * Option definition. Used in options definition lists, with optional alter
- * operation.
- */
-typedef struct OptionDefElem
-{
- NodeTag type;
- AlterOptionOp alter_op; /* Alter operation: ADD/SET/DROP */
- DefElem *def; /* The actual definition */
-} OptionDefElem;
-
-/*
- * Reloption definition. As DefElem, with optional option namespace.
- */
-typedef struct ReloptElem
-{
- NodeTag type;
- char *nmspc;
- char *optname;
- Node *arg;
-} ReloptElem;
-
-/*
* LockingClause - raw representation of FOR UPDATE/SHARE options
*
* Note: lockedRels == NIL means "all relations in query". Otherwise it