/* Write a character-string (possibly NULL) field */
 #define WRITE_STRING_FIELD(fldname) \
        (appendStringInfo(str, " :" CppAsString(fldname) " "), \
-        _outToken(str, node->fldname))
+        outToken(str, node->fldname))
 
 /* Write a parse location field (actually same as INT case) */
 #define WRITE_LOCATION_FIELD(fldname) \
 /* Write a bitmapset field */
 #define WRITE_BITMAPSET_FIELD(fldname) \
        (appendStringInfo(str, " :" CppAsString(fldname) " "), \
-        _outBitmapset(str, node->fldname))
+        outBitmapset(str, node->fldname))
 
 
 #define booltostr(x)  ((x) ? "true" : "false")
 
 
 /*
- * _outToken
+ * outToken
  *       Convert an ordinary string (eg, an identifier) into a form that
  *       will be decoded back to a plain token by read.c's functions.
  *
  *       If a null or empty string is given, it is encoded as "<>".
  */
-static void
-_outToken(StringInfo str, const char *s)
+void
+outToken(StringInfo str, const char *s)
 {
        if (s == NULL || *s == '\0')
        {
        }
 }
 
-/* for use by extensions which define extensible nodes */
-void
-outToken(StringInfo str, const char *s)
-{
-       _outToken(str, s);
-}
-
 static void
 _outList(StringInfo str, const List *node)
 {
 }
 
 /*
- * _outBitmapset -
+ * outBitmapset -
  *        converts a bitmap set of integers
  *
  * Note: the output format is "(b int int ...)", similar to an integer List.
  */
-static void
-_outBitmapset(StringInfo str, const Bitmapset *bms)
+void
+outBitmapset(StringInfo str, const Bitmapset *bms)
 {
        int                     x;
 
        appendStringInfoChar(str, ')');
 }
 
-/* for use by extensions which define extensible nodes */
-void
-outBitmapset(StringInfo str, const Bitmapset *bms)
-{
-       _outBitmapset(str, bms);
-}
-
 /*
  * Print the value of a Datum given its type.
  */
        WRITE_BITMAPSET_FIELD(custom_relids);
        /* CustomName is a key to lookup CustomScanMethods */
        appendStringInfoString(str, " :methods ");
-       _outToken(str, node->methods->CustomName);
+       outToken(str, node->methods->CustomName);
 }
 
 static void
                        break;
        }
        appendStringInfoString(str, " :boolop ");
-       _outToken(str, opstr);
+       outToken(str, opstr);
 
        WRITE_NODE_FIELD(args);
        WRITE_LOCATION_FIELD(location);
 {
        WRITE_ENUM_FIELD(pathtype, NodeTag);
        appendStringInfoString(str, " :parent_relids ");
-       _outBitmapset(str, node->parent->relids);
+       outBitmapset(str, node->parent->relids);
        if (node->pathtarget != node->parent->reltarget)
                WRITE_NODE_FIELD(pathtarget);
        appendStringInfoString(str, " :required_outer ");
        if (node->param_info)
-               _outBitmapset(str, node->param_info->ppi_req_outer);
+               outBitmapset(str, node->param_info->ppi_req_outer);
        else
-               _outBitmapset(str, NULL);
+               outBitmapset(str, NULL);
        WRITE_BOOL_FIELD(parallel_aware);
        WRITE_BOOL_FIELD(parallel_safe);
        WRITE_INT_FIELD(parallel_workers);
        WRITE_NODE_FIELD(custom_paths);
        WRITE_NODE_FIELD(custom_private);
        appendStringInfoString(str, " :methods ");
-       _outToken(str, node->methods->CustomName);
+       outToken(str, node->methods->CustomName);
 }
 
 static void
                case T_String:
 
                        /*
-                        * We use _outToken to provide escaping of the string's content,
+                        * 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 (value->val.str[0] != '\0')
-                               _outToken(str, value->val.str);
+                               outToken(str, value->val.str);
                        appendStringInfoChar(str, '"');
                        break;
                case T_BitString:
        outNode(&str, obj);
        return str.data;
 }
+
+/*
+ * bmsToString -
+ *        returns the ascii representation of the Bitmapset as a palloc'd string
+ */
+char *
+bmsToString(const Bitmapset *bms)
+{
+       StringInfoData str;
+
+       /* see stringinfo.h for an explanation of this maneuver */
+       initStringInfo(&str);
+       outBitmapset(&str, bms);
+       return str.data;
+}