*** src/backend/utils/adt/xml.c.old	Fri Sep  4 12:49:43 2009
--- src/backend/utils/adt/xml.c	Wed Jan  6 21:32:22 2010
***************
*** 111,116 ****
--- 111,117 ----
  static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg,
  		  bool preserve_whitespace, int encoding);
  static text *xml_xmlnodetoxmltype(xmlNodePtr cur);
+ static text *xml_xmlpathobjtoxmltype(xmlXPathObjectPtr cur);
  #endif   /* USE_LIBXML */
  
  static StringInfo query_to_xml_internal(const char *query, char *tablename,
***************
*** 3265,3270 ****
--- 3266,3312 ----
  
  	return result;
  }
+ 
+ /*
+  * Convert XML pathobject to text for non-nodeset objects
+  */
+ static text *
+ xml_xmlpathobjtoxmltype(xmlXPathObjectPtr cur)
+ {
+ 	xmltype    *result;
+ 
+ 	if (cur->type == XPATH_BOOLEAN)
+ 	{
+ 		PG_TRY();
+ 		{
+ 			result = cstring_to_text((char *)(xmlXPathCastToBoolean(cur)?"t":"f"));
+ 		}
+ 		PG_CATCH();
+ 		{
+ 			PG_RE_THROW();
+ 		}
+ 		PG_END_TRY();
+ 	}
+ 	else
+ 	{
+ 		xmlChar    *str;
+ 
+ 		str = xmlXPathCastToString(cur);
+ 		PG_TRY();
+ 		{
+ 			result = (xmltype *) cstring_to_text((char *) str);
+ 		}
+ 		PG_CATCH();
+ 		{
+ 			xmlFree(str);
+ 			PG_RE_THROW();
+ 		}
+ 		PG_END_TRY();
+ 		xmlFree(str);
+ 	}
+ 
+ 	return result;
+ }
  #endif
  
  
***************
*** 3418,3442 ****
  			xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
  						"could not create XPath object");
  
! 		/* return empty array in cases when nothing is found */
! 		if (xpathobj->nodesetval == NULL)
! 			res_nitems = 0;
! 		else
! 			res_nitems = xpathobj->nodesetval->nodeNr;
! 
! 		if (res_nitems)
! 		{
! 			for (i = 0; i < xpathobj->nodesetval->nodeNr; i++)
  			{
! 				Datum		elem;
! 				bool		elemisnull = false;
! 
! 				elem = PointerGetDatum(xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i]));
! 				astate = accumArrayResult(astate, elem,
! 										  elemisnull, XMLOID,
! 										  CurrentMemoryContext);
  			}
  		}
  	}
  	PG_CATCH();
  	{
--- 3460,3504 ----
  			xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
  						"could not create XPath object");
  
! 		switch (xpathobj->type) {
! 		case XPATH_NODESET: {
! 			/* return empty array in cases when nothing is found */
! 			if (xpathobj->nodesetval == NULL)
! 				res_nitems = 0;
! 			else
! 				res_nitems = xpathobj->nodesetval->nodeNr;
! 	
! 			if (res_nitems)
  			{
! 				for (i = 0; i < xpathobj->nodesetval->nodeNr; i++)
! 				{
! 					Datum		elem;
! 					bool		elemisnull = false;
! 	
! 					elem = PointerGetDatum(xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i]));
! 					astate = accumArrayResult(astate, elem,
! 										  	elemisnull, XMLOID,
! 										  	CurrentMemoryContext);
! 				}
  			}
+ 			break;
  		}
+ 		case XPATH_BOOLEAN:
+ 		case XPATH_NUMBER:
+ 		case XPATH_STRING: {
+ 			Datum		elem;
+ 			bool		elemisnull = false;
+ 	
+ 			elem = PointerGetDatum(xml_xmlpathobjtoxmltype(xpathobj));
+ 			astate = accumArrayResult(astate, elem,
+ 						  	elemisnull, XMLOID,
+ 						  	CurrentMemoryContext);
+ 			break;
+ 		}
+ 		default: {
+ 			ereport(WARNING, (errmsg("Unknown PathObjectType (%d)", xpathobj->type)));
+ 		}
+ 		}
  	}
  	PG_CATCH();
  	{
***************
*** 3460,3466 ****
  	xmlFreeDoc(doc);
  	xmlFreeParserCtxt(ctxt);
  
! 	if (res_nitems == 0)
  		PG_RETURN_ARRAYTYPE_P(construct_empty_array(XMLOID));
  	else
  		PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext));
--- 3522,3528 ----
  	xmlFreeDoc(doc);
  	xmlFreeParserCtxt(ctxt);
  
! 	if (astate == NULL)
  		PG_RETURN_ARRAYTYPE_P(construct_empty_array(XMLOID));
  	else
  		PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext));

