Re: [HACKERS] [PATCHES] xpath_array with namespaces support

2007-04-04 Thread Nikolay Samokhvalov

On 3/23/07, Peter Eisentraut <[EMAIL PROTECTED]> wrote:


Andrew Dunstan wrote:
> Would it be better to use some more unlikely name for the dummy root
> element used to process fragments than  ?

Why do we even need to support xpath on fragments?



Why not? I find it useful and convenient.

--
Best regards,
Nikolay


Re: [HACKERS] [PATCHES] xpath_array with namespaces support

2007-04-04 Thread Nikolay Samokhvalov

On 4/4/07, Peter Eisentraut <[EMAIL PROTECTED]> wrote:


Am Mittwoch, 4. April 2007 14:43 schrieb Nikolay Samokhvalov:
> > Why do we even need to support xpath on fragments?
>
> Why not? I find it useful and convenient.

Well, rather than inventing bogus root wrapper elements, why not let users
call xmlelement() to produce the wrapper element themselves?



User may even don't know in what case wrapper element is needed. I mean, if
user works with XML column containing both documents and fragments, then
what must he do? Add wrapper anyway? So, users will add XMLELEMENT in almost
any case.

I'd prefer to keep external interfaces simpler (less thinking in such cases
for users).

--
Best regards,
Nikolay


Re: [HACKERS] [PATCHES] xpath_array with namespaces support

2007-04-04 Thread Peter Eisentraut
Am Mittwoch, 4. April 2007 14:43 schrieb Nikolay Samokhvalov:
> > Why do we even need to support xpath on fragments?
>
> Why not? I find it useful and convenient.

Well, rather than inventing bogus root wrapper elements, why not let users 
call xmlelement() to produce the wrapper element themselves?

-- 
Peter Eisentraut
http://developer.postgresql.org/~petere/

---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [HACKERS] [PATCHES] xpath_array with namespaces support

2007-03-22 Thread Peter Eisentraut
Andrew Dunstan wrote:
> Would it be better to use some more unlikely name for the dummy root
> element used to process fragments than  ?

Why do we even need to support xpath on fragments?

-- 
Peter Eisentraut
http://developer.postgresql.org/~petere/

---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faq


Re: [HACKERS] [PATCHES] xpath_array with namespaces support

2007-03-22 Thread Bruce Momjian

Applying newest version of this patch now;  still needs documentation.

---

Nikolay Samokhvalov wrote:
> On 3/5/07, Nikolay Samokhvalov <[EMAIL PROTECTED]> wrote:
> > On 3/4/07, Nikolay Samokhvalov <[EMAIL PROTECTED]> wrote:
> > > I'll fix these issues and extend the patch with resgression tests and
> > > docs for xpath_array(). I'll resubmit it very soon.
> >
> > Here is a new version of the patch. I didn't change any part of docs yet.
> > Since there were no objections I've changed the name of the function
> > to xmlpath().
> 
> Updated version of the patch contains bugfix: there were a problem
> with path queries that pointed to elements (cases when a set of
> document parts that correspond to subtrees should be returned).
> Example is (included in regression test):
> 
> xmltest=# SELECT xmlpath('//b', 'one two three etc');
>  xmlpath
> -
>  {two,etc}
> (1 row)
> 
> Waiting for more feedback, please check it.
> 
> -- 
> Best regards,
> Nikolay

[ Attachment, skipping... ]

> 
> ---(end of broadcast)---
> TIP 5: don't forget to increase your free space map settings

-- 
  Bruce Momjian  <[EMAIL PROTECTED]>  http://momjian.us
  EnterpriseDB   http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
   choose an index scan if your joining column's datatypes do not
   match


Re: [HACKERS] [PATCHES] xpath_array with namespaces support

2007-03-18 Thread Nikolay Samokhvalov

On 3/17/07, Andrew Dunstan <[EMAIL PROTECTED]> wrote:

In principle I am in favor of the patch.

Would it be better to use some more unlikely name for the dummy root
element used to process fragments than  ?

Perhaps even something in a special namespace?



I did think about it, but I didn't find any difficulties with simple
 The thing is that regardless the element name we have
corresponding shift in XPath epression -- so, there cannot be any
problem from my point of view... But maybe I don't see something and
it's better to avoid _possible_ problem. It depends on PostgreSQL code
style itself -- what is the best approach in such cases? To avoid
unknown possible difficulties or to be clear?

--
Best regards,
Nikolay

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [HACKERS] [PATCHES] xpath_array with namespaces support

2007-03-18 Thread Nikolay Samokhvalov

On 3/5/07, Nikolay Samokhvalov <[EMAIL PROTECTED]> wrote:

On 3/4/07, Nikolay Samokhvalov <[EMAIL PROTECTED]> wrote:
> I'll fix these issues and extend the patch with resgression tests and
> docs for xpath_array(). I'll resubmit it very soon.

Here is a new version of the patch. I didn't change any part of docs yet.
Since there were no objections I've changed the name of the function
to xmlpath().


Updated version of the patch contains bugfix: there were a problem
with path queries that pointed to elements (cases when a set of
document parts that correspond to subtrees should be returned).
Example is (included in regression test):

xmltest=# SELECT xmlpath('//b', 'one two three etc');
xmlpath
-
{two,etc}
(1 row)

Waiting for more feedback, please check it.

--
Best regards,
Nikolay
Index: src/backend/utils/adt/xml.c
===
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/xml.c,v
retrieving revision 1.35
diff -u -r1.35 xml.c
--- src/backend/utils/adt/xml.c	15 Mar 2007 23:12:06 -	1.35
+++ src/backend/utils/adt/xml.c	18 Mar 2007 13:32:21 -
@@ -47,6 +47,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #endif /* USE_LIBXML */
 
 #include "catalog/namespace.h"
@@ -67,6 +69,7 @@
 #include "utils/datetime.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
+#include "access/tupmacs.h"
 #include "utils/xml.h"
 
 
@@ -88,6 +91,7 @@
 static int		parse_xml_decl(const xmlChar *str, size_t *lenp, xmlChar **version, xmlChar **encoding, int *standalone);
 static bool		print_xml_decl(StringInfo buf, const xmlChar *version, pg_enc encoding, int standalone);
 static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, xmlChar *encoding);
+static text		*xml_xmlnodetoxmltype(xmlNodePtr cur);
 
 #endif /* USE_LIBXML */
 
@@ -1463,7 +1467,6 @@
 	return buf.data;
 }
 
-
 /*
  * Map SQL value to XML value; see SQL/XML:2003 section 9.16.
  */
@@ -2403,3 +2406,258 @@
 	else
 		appendStringInfoString(result, "\n\n");
 }
+
+
+/*
+ * XPath related functions
+ */
+
+#ifdef USE_LIBXML
+/* 
+ * Convert XML node to text (dump subtree in case of element, return value otherwise)
+ */
+text *
+xml_xmlnodetoxmltype(xmlNodePtr cur)
+{
+	xmlChar			*str;
+	xmltype*result;
+	size_tlen;
+	xmlBufferPtr 		buf;
+	
+	if (cur->type == XML_ELEMENT_NODE)
+	{
+		buf = xmlBufferCreate();
+		xmlNodeDump(buf, NULL, cur, 0, 1);
+		result = xmlBuffer_to_xmltype(buf);
+		xmlBufferFree(buf);
+	}
+	else
+	{
+		str = xmlXPathCastNodeToString(cur);
+		len = strlen((char *) str);
+		result = (text *) palloc(len + VARHDRSZ);
+		SET_VARSIZE(result, len + VARHDRSZ);
+		memcpy(VARDATA(result), str, len);
+	}
+	
+	return result;
+}
+#endif
+
+/*
+ * Evaluate XPath expression and return array of XML values.
+ * As we have no support of XQuery sequences yet, this functions seems
+ * to be the most useful one (array of XML functions plays a role of
+ * some kind of substritution for XQuery sequences).
+
+ * Workaround here: we parse XML data in different way to allow XPath for
+ * fragments (see "XPath for fragment" TODO comment inside).
+ */
+Datum
+xmlpath(PG_FUNCTION_ARGS)
+{
+#ifdef USE_LIBXML
+	ArrayBuildState		*astate = NULL;
+	xmlParserCtxtPtr	ctxt = NULL;
+	xmlDocPtr			doc = NULL;
+	xmlXPathContextPtr	xpathctx = NULL;
+	xmlXPathCompExprPtr	xpathcomp = NULL;
+	xmlXPathObjectPtr	xpathobj = NULL;
+	int32len, xpath_len;
+	xmlChar*string, *xpath_expr;
+	boolres_is_null = FALSE;
+	int	i;
+	xmltype*data;
+	text*xpath_expr_text;
+	ArrayType			*namespaces;
+	int	*dims, ndims, ns_count = 0, bitmask = 1;
+	char*ptr;
+	bits8*bitmap;
+	char**ns_names = NULL, **ns_uris = NULL;
+	int16typlen;
+	booltypbyval;
+	chartypalign;
+	
+	/* the function is not strict, we must check first two args */
+	if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
+		PG_RETURN_NULL();
+	
+	xpath_expr_text = PG_GETARG_TEXT_P(0);
+	data  = PG_GETARG_XML_P(1);
+	
+	/* Namespace mappings passed as text[].
+	 * Assume that 2-dimensional array has been passed, 
+	 * the 1st subarray is array of names, the 2nd -- array of URIs,
+	 * example: ARRAY[ARRAY['myns', 'myns2'], ARRAY['http://example.com', 'http://example2.com']]. 
+	 */
+	if (!PG_ARGISNULL(2))
+	{
+		namespaces = PG_GETARG_ARRAYTYPE_P(2);
+		ndims = ARR_NDIM(namespaces);
+		dims = ARR_DIMS(namespaces);
+		
+		/* Sanity check */
+		if (ndims != 2)
+			ereport(ERROR, (errmsg("invalid array passed for namespace mappings"),
+			errdetail("Only 2-dimensional array may be used for namespace mappings.")));
+		
+		Assert(ARR_ELEMTYPE(namespaces) == TEXTOID);
+		
+		ns_count = ArrayGetNItems(ndims, dims) / 2;
+		get_typlenbyvalalign(ARR_ELEMTYPE(namespaces),
+			 &typlen, &typbyval, &typalign);
+		ns_names = (char **) palloc(ns_count * sizeof(char *));
+		ns_uris = (char **) palloc(ns_count * sizeof(char *));
+		ptr = ARR_DATA_PTR(names

Re: [HACKERS] [PATCHES] xpath_array with namespaces support

2007-03-17 Thread Andrew Dunstan



Nikolay Samokhvalov wrote:

On 3/17/07, Andrew Dunstan <[EMAIL PROTECTED]> wrote:

In principle I am in favor of the patch.

Would it be better to use some more unlikely name for the dummy root
element used to process fragments than  ?

Perhaps even something in a special namespace?



I did think about it, but I didn't find any difficulties with simple
 The thing is that regardless the element name we have
corresponding shift in XPath epression -- so, there cannot be any
problem from my point of view... But maybe I don't see something and
it's better to avoid _possible_ problem. It depends on PostgreSQL code
style itself -- what is the best approach in such cases? To avoid
unknown possible difficulties or to be clear?



If you are sure that it won't cause a problem then I think it's ok to 
leave it, as long as there is a comment in the code that says why we are 
sure it's ok.


cheers

andrew

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [HACKERS] [PATCHES] xpath_array with namespaces support

2007-03-17 Thread Andrew Dunstan



Nikolay Samokhvalov wrote:
What about it? W/o this not large patch XML functionality in 8.3 will 
be weak...

Will it be accepted?



In principle I am in favor of the patch.

Would it be better to use some more unlikely name for the dummy root 
element used to process fragments than  ?


Perhaps even something in a special namespace?

cheers

andrew




---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

  http://www.postgresql.org/docs/faq


Re: [HACKERS] [PATCHES] xpath_array with namespaces support

2007-03-17 Thread Nikolay Samokhvalov

What about it? W/o this not large patch XML functionality in 8.3 will be weak...
Will it be accepted?

On 3/5/07, Nikolay Samokhvalov <[EMAIL PROTECTED]> wrote:

On 3/4/07, Nikolay Samokhvalov <[EMAIL PROTECTED]> wrote:
> I'll fix these issues and extend the patch with resgression tests and
> docs for xpath_array(). I'll resubmit it very soon.

Here is a new version of the patch. I didn't change any part of docs yet.
Since there were no objections I've changed the name of the function
to xmlpath().




--
Best regards,
Nikolay
Index: src/backend/utils/adt/xml.c
===
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/xml.c,v
retrieving revision 1.34
diff -u -r1.34 xml.c
--- src/backend/utils/adt/xml.c	3 Mar 2007 19:32:55 -	1.34
+++ src/backend/utils/adt/xml.c	5 Mar 2007 01:14:57 -
@@ -47,6 +47,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #endif /* USE_LIBXML */
 
 #include "catalog/namespace.h"
@@ -67,6 +69,7 @@
 #include "utils/datetime.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
+#include "access/tupmacs.h"
 #include "utils/xml.h"
 
 
@@ -88,6 +91,7 @@
 static int		parse_xml_decl(const xmlChar *str, size_t *lenp, xmlChar **version, xmlChar **encoding, int *standalone);
 static bool		print_xml_decl(StringInfo buf, const xmlChar *version, pg_enc encoding, int standalone);
 static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, xmlChar *encoding);
+static text		*xml_xmlnodetotext(xmlNodePtr cur);
 
 #endif /* USE_LIBXML */
 
@@ -1463,7 +1467,6 @@
 	return buf.data;
 }
 
-
 /*
  * Map SQL value to XML value; see SQL/XML:2003 section 9.16.
  */
@@ -2403,3 +2406,247 @@
 	else
 		appendStringInfoString(result, "\n\n");
 }
+
+
+/*
+ * XPath related functions
+ */
+
+#ifdef USE_LIBXML
+/* 
+ * Convert XML node to text (return value only, it's not dumping)
+ */
+text *
+xml_xmlnodetotext(xmlNodePtr cur)
+{
+	xmlChar		*str;
+	text			*result;
+	size_t			len;	
+	
+	str = xmlXPathCastNodeToString(cur);
+	len = strlen((char *) str);
+	result = (text *) palloc(len + VARHDRSZ);
+	SET_VARSIZE(result, len + VARHDRSZ);
+	memcpy(VARDATA(result), str, len);
+	
+	return result;
+}
+#endif
+
+/*
+ * Evaluate XPath expression and return array of XML values.
+ * As we have no support of XQuery sequences yet, this functions seems
+ * to be the most useful one (array of XML functions plays a role of
+ * some kind of substritution for XQuery sequences).
+
+ * Workaround here: we parse XML data in different way to allow XPath for
+ * fragments (see "XPath for fragment" TODO comment inside).
+ */
+Datum
+xmlpath(PG_FUNCTION_ARGS)
+{
+#ifdef USE_LIBXML
+	ArrayBuildState		*astate = NULL;
+	xmlParserCtxtPtr	ctxt = NULL;
+	xmlDocPtr			doc = NULL;
+	xmlXPathContextPtr	xpathctx = NULL;
+	xmlXPathCompExprPtr	xpathcomp = NULL;
+	xmlXPathObjectPtr	xpathobj = NULL;
+	int32len, xpath_len;
+	xmlChar*string, *xpath_expr;
+	boolres_is_null = FALSE;
+	int	i;
+	xmltype*data;
+	text*xpath_expr_text;
+	ArrayType			*namespaces;
+	int	*dims, ndims, ns_count = 0, bitmask = 1;
+	char*ptr;
+	bits8*bitmap;
+	char**ns_names = NULL, **ns_uris = NULL;
+	int16typlen;
+	booltypbyval;
+	chartypalign;
+	
+	/* the function is not strict, we must check first two args */
+	if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
+		PG_RETURN_NULL();
+	
+	xpath_expr_text = PG_GETARG_TEXT_P(0);
+	data  = PG_GETARG_XML_P(1);
+	
+	/* Namespace mappings passed as text[].
+	 * Assume that 2-dimensional array has been passed, 
+	 * the 1st subarray is array of names, the 2nd -- array of URIs,
+	 * example: ARRAY[ARRAY['myns', 'myns2'], ARRAY['http://example.com', 'http://example2.com']]. 
+	 */
+	if (!PG_ARGISNULL(2))
+	{
+		namespaces = PG_GETARG_ARRAYTYPE_P(2);
+		ndims = ARR_NDIM(namespaces);
+		dims = ARR_DIMS(namespaces);
+		
+		/* Sanity check */
+		if (ndims != 2)
+			ereport(ERROR, (errmsg("invalid array passed for namespace mappings"),
+			errdetail("Only 2-dimensional array may be used for namespace mappings.")));
+		
+		Assert(ARR_ELEMTYPE(namespaces) == TEXTOID);
+		
+		ns_count = ArrayGetNItems(ndims, dims) / 2;
+		get_typlenbyvalalign(ARR_ELEMTYPE(namespaces),
+			 &typlen, &typbyval, &typalign);
+		ns_names = (char **) palloc(ns_count * sizeof(char *));
+		ns_uris = (char **) palloc(ns_count * sizeof(char *));
+		ptr = ARR_DATA_PTR(namespaces);
+		bitmap = ARR_NULLBITMAP(namespaces);
+		bitmask = 1;
+		
+		for (i = 0; i < ns_count * 2; i++)
+		{
+			if (bitmap && (*bitmap & bitmask) == 0)
+ereport(ERROR, (errmsg("neither namespace nor URI may be NULL"))); /* TODO: better message */
+			else
+			{
+if (i < ns_count)
+	ns_names[i] = DatumGetCString(DirectFunctionCall1(textout,
+		  PointerGetDatum(ptr)));
+else
+	ns_uris[i - ns_count] = DatumGetCString(DirectFunctionCall1(textout,
+		  PointerGetDatum(ptr)));
+ptr = att_ad