Remove the recently added node types ReloptElem and OptionDefElem in favor
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 4 Apr 2009 21:12:31 +0000 (21:12 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 4 Apr 2009 21:12:31 +0000 (21:12 +0000)
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.

17 files changed:
src/backend/access/common/reloptions.c
src/backend/commands/define.c
src/backend/commands/foreigncmds.c
src/backend/commands/sequence.c
src/backend/commands/typecmds.c
src/backend/commands/view.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/makefuncs.c
src/backend/nodes/outfuncs.c
src/backend/parser/gram.y
src/backend/parser/parse_clause.c
src/include/commands/defrem.h
src/include/foreign/foreign.h
src/include/nodes/makefuncs.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h

index ae14e1193bcafbeb2b832e427f37287729aa7021..4b0bfb9f013e46292c0f97b3de2b40f6f8d07dff 100644 (file)
@@ -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,
index a5d2d55bda37536853baba3fe25d1de9aa674e9d..2d6343aa1960a3c0fe1f22edce89682cdd122287 100644 (file)
@@ -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,28 +81,19 @@ 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.
  */
@@ -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,19 +163,11 @@ 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.
  */
@@ -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));
 }
index 84b7ffac4bc3ba97dfbc274273524e2505be09e3..52abcc25720f2c9c30a86a3fed3a493e2888c881 100644 (file)
@@ -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;
index 2f178054f283ee5e5ff9a6ca029fb9a6a0a36259..46d76833771d7ff64c2774adadd14081998157ff 100644 (file)
@@ -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;
 
index 98e01e455b910d23253acf47a11af832b61475bd..7d4c363c47b50e3c8db837b315ca980376ec779b 100644 (file)
@@ -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;
 
index 60dcfb3c774c6f2d85335f6c472c63d40fecbb29..ac70facce7c4facd9b7867af2bc4b084da720a13 100644 (file)
@@ -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;
 
index 01e5fc219bea59cb0fa7da42d11efc317456393b..3a51aca78eefc38e9fcb61a1f728ed7bb9efcc07 100644 (file)
@@ -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;
index 3e0487beeff1495f9220e49e1d06553189a6b512..537bf68e19ef55747e9be4c7b1ee41bd7eeb8f6b 100644 (file)
@@ -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;
index 440577048ba757a84e46005f6f1f80e4bbe93274..6e3cc13d3c79b812e6c7aac8e1ce49a90f14ee45 100644 (file)
@@ -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;
 }
index 68a44339da5d62b46bb9f356827d83eea48a06fd..236ae60c8ab5ed4c07fa6b4b51d4577eb1377db1 100644 (file)
@@ -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;
index 7c45f68e23538c98cf37e76ff288de0a7fbce9a4..e1de04e7611bd9fb62117c7a813f693dcadb90d4 100644 (file)
@@ -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
                                {
index ef548a7aff52e92fb1f7693e43f05e6b8cc1fa4c..f566d4c7a34fc9e17e19a395bc47236ae255cfcc 100644 (file)
@@ -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. */
index 64af22cbd6cf0fe8d187d22f85eee46ec751fbc1..4356492c97541e8a69add4745835fe28416718a5 100644 (file)
@@ -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 */
index e068e682a3e618bd2b0da0d6fa1f102a752aeb3f..fd2773140e3b517869eb7d73063bf57910ef9f8b 100644 (file)
@@ -14,7 +14,6 @@
 #define FOREIGN_H
 
 #include "nodes/parsenodes.h"
-#include "nodes/pg_list.h"
 
 
 /* Helper for obtaining username for user mapping */
  * 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 */
index cd7bedfb42ade2dbf775afed493566b5056fc086..3a2a7f4010330a71b6350543cf5c5efa0eaceff6 100644 (file)
@@ -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 */
index 2620a80407b32f93b14fda78350581fcb4e926c6..30ee53dc9b5535c692ae2f38117d651e3573207c 100644 (file)
@@ -361,8 +361,6 @@ typedef enum NodeTag
        T_IndexElem,
        T_Constraint,
        T_DefElem,
-       T_OptionDefElem,
-       T_ReloptElem,
        T_RangeTblEntry,
        T_SortGroupClause,
        T_WindowClause,
index 3fc17b5a707baa30d9b8387ffffda046c37a8083..6d3265f8b06e988635d929750647c496ddc513c4 100644 (file)
@@ -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,38 +503,32 @@ 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
  *