* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.69 2008/03/01 02:46:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.76 2008/08/25 22:42:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/execnodes.h"
-#include "parser/parse_expr.h"
+#include "nodes/nodeFuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/datetime.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
-#include "access/tupmacs.h"
#include "utils/xml.h"
/* GUC variables */
-XmlBinaryType xmlbinary;
-XmlOptionType xmloption;
+int xmlbinary;
+int xmloption;
#ifdef USE_LIBXML
errhint("You need to rebuild PostgreSQL using --with-libxml.")))
-#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
-#define _textout(x) DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(x)))
-
-
/* from SQL/XML:2003 section 4.7 */
#define NAMESPACE_XSD "http://www.w3.org/2001/XMLSchema"
#define NAMESPACE_XSI "http://www.w3.org/2001/XMLSchema-instance"
#endif
+/*
+ * xml_in uses a plain C string to VARDATA conversion, so for the time being
+ * we use the conversion function for the text datatype.
+ *
+ * This is only acceptable so long as xmltype and text use the same
+ * representation.
+ */
Datum
xml_in(PG_FUNCTION_ARGS)
{
#ifdef USE_LIBXML
char *s = PG_GETARG_CSTRING(0);
- size_t len;
xmltype *vardata;
xmlDocPtr doc;
- len = strlen(s);
- vardata = palloc(len + VARHDRSZ);
- SET_VARSIZE(vardata, len + VARHDRSZ);
- memcpy(VARDATA(vardata), s, len);
+ vardata = (xmltype *) cstring_to_text(s);
/*
* Parse the data to check if it is well-formed XML data. Assume that
#define PG_XML_DEFAULT_VERSION "1.0"
+/*
+ * xml_out_internal uses a plain VARDATA to C string conversion, so for the
+ * time being we use the conversion function for the text datatype.
+ *
+ * This is only acceptable so long as xmltype and text use the same
+ * representation.
+ */
static char *
xml_out_internal(xmltype *x, pg_enc target_encoding)
{
int res_code;
#endif
- len = VARSIZE(x) - VARHDRSZ;
- str = palloc(len + 1);
- memcpy(str, VARDATA(x), len);
- str[len] = '\0';
+ str = text_to_cstring((text *) x);
+ len = strlen(str);
#ifdef USE_LIBXML
if ((res_code = parse_xml_decl((xmlChar *) str,
if (newstr != str)
{
pfree(result);
-
- nbytes = strlen(newstr);
-
- result = palloc(nbytes + VARHDRSZ);
- SET_VARSIZE(result, nbytes + VARHDRSZ);
- memcpy(VARDATA(result), newstr, nbytes);
-
+ result = (xmltype *) cstring_to_text(newstr);
pfree(newstr);
}
static xmltype *
stringinfo_to_xmltype(StringInfo buf)
{
- int32 len;
- xmltype *result;
-
- len = buf->len + VARHDRSZ;
- result = palloc(len);
- SET_VARSIZE(result, len);
- memcpy(VARDATA(result), buf->data, buf->len);
-
- return result;
+ return (xmltype *) cstring_to_text_with_len(buf->data, buf->len);
}
static xmltype *
cstring_to_xmltype(const char *string)
{
- int32 len;
- xmltype *result;
-
- len = strlen(string) + VARHDRSZ;
- result = palloc(len);
- SET_VARSIZE(result, len);
- memcpy(VARDATA(result), string, len - VARHDRSZ);
-
- return result;
+ return (xmltype *) cstring_to_text(string);
}
static xmltype *
xmlBuffer_to_xmltype(xmlBufferPtr buf)
{
- int32 len;
- xmltype *result;
-
- len = xmlBufferLength(buf) + VARHDRSZ;
- result = palloc(len);
- SET_VARSIZE(result, len);
- memcpy(VARDATA(result), xmlBufferContent(buf), len - VARHDRSZ);
-
- return result;
+ return (xmltype *) cstring_to_text_with_len((char *) xmlBufferContent(buf),
+ xmlBufferLength(buf));
}
#endif
char *str;
len = VARSIZE(x) - VARHDRSZ;
- str = palloc(len + 1);
- memcpy(str, VARDATA(x), len);
- str[len] = '\0';
+ str = text_to_cstring((text *) x);
parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone);
{
char *string;
- string = _textout(arg);
+ string = text_to_cstring(arg);
if (strstr(string, "?>") != NULL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
StringInfoData buf;
len = VARSIZE(data) - VARHDRSZ;
- str = palloc(len + 1);
- memcpy(str, VARDATA(data), len);
- str[len] = '\0';
+ str = text_to_cstring((text *) data);
parse_xml_decl((xmlChar *) str, &len, &orig_version, NULL, &orig_standalone);
/*
- * xmlChar<->text convertions
+ * xmlChar<->text conversions
*/
static xmlChar *
xml_text2xmlChar(text *in)
{
- int32 len = VARSIZE(in) - VARHDRSZ;
- xmlChar *res;
-
- res = palloc(len + 1);
- memcpy(res, VARDATA(in), len);
- res[len] = '\0';
-
- return (res);
+ return (xmlChar *) text_to_cstring(in);
}
switch (code)
{
case XML_ERR_INVALID_CHAR:
- det = "Invalid character value";
+ det = gettext_noop("Invalid character value.");
break;
case XML_ERR_SPACE_REQUIRED:
- det = "Space required";
+ det = gettext_noop("Space required.");
break;
case XML_ERR_STANDALONE_VALUE:
- det = "standalone accepts only 'yes' or 'no'";
+ det = gettext_noop("standalone accepts only 'yes' or 'no'.");
break;
case XML_ERR_VERSION_MISSING:
- det = "Malformed declaration expecting version";
+ det = gettext_noop("Malformed declaration: missing version.");
break;
case XML_ERR_MISSING_ENCODING:
- det = "Missing encoding in text declaration";
+ det = gettext_noop("Missing encoding in text declaration.");
break;
case XML_ERR_XMLDECL_NOT_FINISHED:
- det = "Parsing XML declaration: '?>' expected";
+ det = gettext_noop("Parsing XML declaration: '?>' expected.");
break;
default:
- det = "Unrecognized libxml error code: %d";
+ det = gettext_noop("Unrecognized libxml error code: %d.");
break;
}
Oid relid = PG_GETARG_OID(0);
bool nulls = PG_GETARG_BOOL(1);
bool tableforest = PG_GETARG_BOOL(2);
- const char *targetns = _textout(PG_GETARG_TEXT_P(3));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
PG_RETURN_XML_P(stringinfo_to_xmltype(table_to_xml_internal(relid, NULL,
nulls, tableforest,
Datum
query_to_xml(PG_FUNCTION_ARGS)
{
- char *query = _textout(PG_GETARG_TEXT_P(0));
+ char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
bool nulls = PG_GETARG_BOOL(1);
bool tableforest = PG_GETARG_BOOL(2);
- const char *targetns = _textout(PG_GETARG_TEXT_P(3));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
PG_RETURN_XML_P(stringinfo_to_xmltype(query_to_xml_internal(query, NULL,
NULL, nulls, tableforest,
Datum
cursor_to_xml(PG_FUNCTION_ARGS)
{
- char *name = _textout(PG_GETARG_TEXT_P(0));
+ char *name = text_to_cstring(PG_GETARG_TEXT_PP(0));
int32 count = PG_GETARG_INT32(1);
bool nulls = PG_GETARG_BOOL(2);
bool tableforest = PG_GETARG_BOOL(3);
- const char *targetns = _textout(PG_GETARG_TEXT_P(4));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(4));
StringInfoData result;
Portal portal;
Oid relid = PG_GETARG_OID(0);
bool nulls = PG_GETARG_BOOL(1);
bool tableforest = PG_GETARG_BOOL(2);
- const char *targetns = _textout(PG_GETARG_TEXT_P(3));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
const char *result;
Relation rel;
Datum
query_to_xmlschema(PG_FUNCTION_ARGS)
{
- char *query = _textout(PG_GETARG_TEXT_P(0));
+ char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
bool nulls = PG_GETARG_BOOL(1);
bool tableforest = PG_GETARG_BOOL(2);
- const char *targetns = _textout(PG_GETARG_TEXT_P(3));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
const char *result;
SPIPlanPtr plan;
Portal portal;
Datum
cursor_to_xmlschema(PG_FUNCTION_ARGS)
{
- char *name = _textout(PG_GETARG_TEXT_P(0));
+ char *name = text_to_cstring(PG_GETARG_TEXT_PP(0));
bool nulls = PG_GETARG_BOOL(1);
bool tableforest = PG_GETARG_BOOL(2);
- const char *targetns = _textout(PG_GETARG_TEXT_P(3));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
const char *xmlschema;
Portal portal;
Oid relid = PG_GETARG_OID(0);
bool nulls = PG_GETARG_BOOL(1);
bool tableforest = PG_GETARG_BOOL(2);
- const char *targetns = _textout(PG_GETARG_TEXT_P(3));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
Relation rel;
const char *xmlschema;
Datum
query_to_xml_and_xmlschema(PG_FUNCTION_ARGS)
{
- char *query = _textout(PG_GETARG_TEXT_P(0));
+ char *query = text_to_cstring(PG_GETARG_TEXT_PP(0));
bool nulls = PG_GETARG_BOOL(1);
bool tableforest = PG_GETARG_BOOL(2);
- const char *targetns = _textout(PG_GETARG_TEXT_P(3));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
const char *xmlschema;
SPIPlanPtr plan;
Name name = PG_GETARG_NAME(0);
bool nulls = PG_GETARG_BOOL(1);
bool tableforest = PG_GETARG_BOOL(2);
- const char *targetns = _textout(PG_GETARG_TEXT_P(3));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
char *schemaname;
Oid nspid;
Name name = PG_GETARG_NAME(0);
bool nulls = PG_GETARG_BOOL(1);
bool tableforest = PG_GETARG_BOOL(2);
- const char *targetns = _textout(PG_GETARG_TEXT_P(3));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
PG_RETURN_XML_P(stringinfo_to_xmltype(schema_to_xmlschema_internal(NameStr(*name),
nulls, tableforest, targetns)));
Name name = PG_GETARG_NAME(0);
bool nulls = PG_GETARG_BOOL(1);
bool tableforest = PG_GETARG_BOOL(2);
- const char *targetns = _textout(PG_GETARG_TEXT_P(3));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(3));
char *schemaname;
Oid nspid;
StringInfo xmlschema;
{
bool nulls = PG_GETARG_BOOL(0);
bool tableforest = PG_GETARG_BOOL(1);
- const char *targetns = _textout(PG_GETARG_TEXT_P(2));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
PG_RETURN_XML_P(stringinfo_to_xmltype(database_to_xml_internal(NULL, nulls,
tableforest, targetns)));
{
bool nulls = PG_GETARG_BOOL(0);
bool tableforest = PG_GETARG_BOOL(1);
- const char *targetns = _textout(PG_GETARG_TEXT_P(2));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
PG_RETURN_XML_P(stringinfo_to_xmltype(database_to_xmlschema_internal(nulls,
tableforest, targetns)));
{
bool nulls = PG_GETARG_BOOL(0);
bool tableforest = PG_GETARG_BOOL(1);
- const char *targetns = _textout(PG_GETARG_TEXT_P(2));
+ const char *targetns = text_to_cstring(PG_GETARG_TEXT_PP(2));
StringInfo xmlschema;
xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns);
{
xmlChar *str;
xmltype *result;
- size_t len;
xmlBufferPtr buf;
if (cur->type == XML_ELEMENT_NODE)
else
{
str = xmlXPathCastNodeToString(cur);
- len = strlen((char *) str);
- result = (text *) palloc(len + VARHDRSZ);
- SET_VARSIZE(result, len + VARHDRSZ);
- memcpy(VARDATA(result), str, len);
+ result = (xmltype *) cstring_to_text((char *) str);
+ xmlFree(str);
}
return result;
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("neither namespace name nor URI may be null")));
- ns_name = _textout(ns_names_uris[i * 2]);
- ns_uri = _textout(ns_names_uris[i * 2 + 1]);
+ ns_name = TextDatumGetCString(ns_names_uris[i * 2]);
+ ns_uri = TextDatumGetCString(ns_names_uris[i * 2 + 1]);
if (xmlXPathRegisterNs(xpathctx,
(xmlChar *) ns_name,
(xmlChar *) ns_uri) != 0)