Initial SQL/XML support: xml data type and initial set of functions.
This commit is contained in:
parent
ed1e9cd501
commit
8c1de5fb00
configureconfigure.in
doc/src/sgml
src
backend
executor
nodes
optimizer/util
parser
utils
include
test/regress
267
configure
vendored
267
configure
vendored
@ -894,6 +894,7 @@ Optional Packages:
|
|||||||
--with-openssl build with OpenSSL support
|
--with-openssl build with OpenSSL support
|
||||||
--without-readline do not use GNU Readline nor BSD Libedit for editing
|
--without-readline do not use GNU Readline nor BSD Libedit for editing
|
||||||
--with-libedit-preferred prefer BSD Libedit over GNU Readline
|
--with-libedit-preferred prefer BSD Libedit over GNU Readline
|
||||||
|
--with-libxml build with XML support
|
||||||
--without-zlib do not use Zlib
|
--without-zlib do not use Zlib
|
||||||
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
|
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
|
||||||
|
|
||||||
@ -4160,6 +4161,42 @@ fi;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# XML
|
||||||
|
#
|
||||||
|
|
||||||
|
pgac_args="$pgac_args with_libxml"
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether --with-libxml or --without-libxml was given.
|
||||||
|
if test "${with_libxml+set}" = set; then
|
||||||
|
withval="$with_libxml"
|
||||||
|
|
||||||
|
case $withval in
|
||||||
|
yes)
|
||||||
|
|
||||||
|
cat >>confdefs.h <<\_ACEOF
|
||||||
|
#define USE_LIBXML 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
;;
|
||||||
|
no)
|
||||||
|
:
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
{ { echo "$as_me:$LINENO: error: no argument expected for --with-libxml option" >&5
|
||||||
|
echo "$as_me: error: no argument expected for --with-libxml option" >&2;}
|
||||||
|
{ (exit 1); exit 1; }; }
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
else
|
||||||
|
with_libxml=no
|
||||||
|
|
||||||
|
fi;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Zlib
|
# Zlib
|
||||||
#
|
#
|
||||||
@ -7268,6 +7305,87 @@ fi
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$with_libxml" = yes ; then
|
||||||
|
|
||||||
|
echo "$as_me:$LINENO: checking for xmlInitParser in -lxml2" >&5
|
||||||
|
echo $ECHO_N "checking for xmlInitParser in -lxml2... $ECHO_C" >&6
|
||||||
|
if test "${ac_cv_lib_xml2_xmlInitParser+set}" = set; then
|
||||||
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
|
else
|
||||||
|
ac_check_lib_save_LIBS=$LIBS
|
||||||
|
LIBS="-lxml2 $LIBS"
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
/* confdefs.h. */
|
||||||
|
_ACEOF
|
||||||
|
cat confdefs.h >>conftest.$ac_ext
|
||||||
|
cat >>conftest.$ac_ext <<_ACEOF
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
/* We use char because int might match the return type of a gcc2
|
||||||
|
builtin and then its argument prototype would still apply. */
|
||||||
|
char xmlInitParser ();
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
xmlInitParser ();
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||||
|
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||||
|
(eval $ac_link) 2>conftest.er1
|
||||||
|
ac_status=$?
|
||||||
|
grep -v '^ *+' conftest.er1 >conftest.err
|
||||||
|
rm -f conftest.er1
|
||||||
|
cat conftest.err >&5
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } &&
|
||||||
|
{ ac_try='test -z "$ac_c_werror_flag"
|
||||||
|
|| test ! -s conftest.err'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; } &&
|
||||||
|
{ ac_try='test -s conftest$ac_exeext'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; }; then
|
||||||
|
ac_cv_lib_xml2_xmlInitParser=yes
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
sed 's/^/| /' conftest.$ac_ext >&5
|
||||||
|
|
||||||
|
ac_cv_lib_xml2_xmlInitParser=no
|
||||||
|
fi
|
||||||
|
rm -f conftest.err conftest.$ac_objext \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
LIBS=$ac_check_lib_save_LIBS
|
||||||
|
fi
|
||||||
|
echo "$as_me:$LINENO: result: $ac_cv_lib_xml2_xmlInitParser" >&5
|
||||||
|
echo "${ECHO_T}$ac_cv_lib_xml2_xmlInitParser" >&6
|
||||||
|
if test $ac_cv_lib_xml2_xmlInitParser = yes; then
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_LIBXML2 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
LIBS="-lxml2 $LIBS"
|
||||||
|
|
||||||
|
else
|
||||||
|
{ { echo "$as_me:$LINENO: error: library 'xml2' is required for XML support" >&5
|
||||||
|
echo "$as_me: error: library 'xml2' is required for XML support" >&2;}
|
||||||
|
{ (exit 1); exit 1; }; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Header files
|
## Header files
|
||||||
@ -10359,6 +10477,155 @@ fi
|
|||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$with_libxml" = yes ; then
|
||||||
|
if test "${ac_cv_header_libxml_parser_h+set}" = set; then
|
||||||
|
echo "$as_me:$LINENO: checking for libxml/parser.h" >&5
|
||||||
|
echo $ECHO_N "checking for libxml/parser.h... $ECHO_C" >&6
|
||||||
|
if test "${ac_cv_header_libxml_parser_h+set}" = set; then
|
||||||
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
|
fi
|
||||||
|
echo "$as_me:$LINENO: result: $ac_cv_header_libxml_parser_h" >&5
|
||||||
|
echo "${ECHO_T}$ac_cv_header_libxml_parser_h" >&6
|
||||||
|
else
|
||||||
|
# Is the header compilable?
|
||||||
|
echo "$as_me:$LINENO: checking libxml/parser.h usability" >&5
|
||||||
|
echo $ECHO_N "checking libxml/parser.h usability... $ECHO_C" >&6
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
/* confdefs.h. */
|
||||||
|
_ACEOF
|
||||||
|
cat confdefs.h >>conftest.$ac_ext
|
||||||
|
cat >>conftest.$ac_ext <<_ACEOF
|
||||||
|
/* end confdefs.h. */
|
||||||
|
$ac_includes_default
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
_ACEOF
|
||||||
|
rm -f conftest.$ac_objext
|
||||||
|
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||||
|
(eval $ac_compile) 2>conftest.er1
|
||||||
|
ac_status=$?
|
||||||
|
grep -v '^ *+' conftest.er1 >conftest.err
|
||||||
|
rm -f conftest.er1
|
||||||
|
cat conftest.err >&5
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } &&
|
||||||
|
{ ac_try='test -z "$ac_c_werror_flag"
|
||||||
|
|| test ! -s conftest.err'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; } &&
|
||||||
|
{ ac_try='test -s conftest.$ac_objext'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; }; then
|
||||||
|
ac_header_compiler=yes
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
sed 's/^/| /' conftest.$ac_ext >&5
|
||||||
|
|
||||||
|
ac_header_compiler=no
|
||||||
|
fi
|
||||||
|
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||||
|
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
|
||||||
|
echo "${ECHO_T}$ac_header_compiler" >&6
|
||||||
|
|
||||||
|
# Is the header present?
|
||||||
|
echo "$as_me:$LINENO: checking libxml/parser.h presence" >&5
|
||||||
|
echo $ECHO_N "checking libxml/parser.h presence... $ECHO_C" >&6
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
/* confdefs.h. */
|
||||||
|
_ACEOF
|
||||||
|
cat confdefs.h >>conftest.$ac_ext
|
||||||
|
cat >>conftest.$ac_ext <<_ACEOF
|
||||||
|
/* end confdefs.h. */
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
_ACEOF
|
||||||
|
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
|
||||||
|
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
|
||||||
|
ac_status=$?
|
||||||
|
grep -v '^ *+' conftest.er1 >conftest.err
|
||||||
|
rm -f conftest.er1
|
||||||
|
cat conftest.err >&5
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } >/dev/null; then
|
||||||
|
if test -s conftest.err; then
|
||||||
|
ac_cpp_err=$ac_c_preproc_warn_flag
|
||||||
|
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
|
||||||
|
else
|
||||||
|
ac_cpp_err=
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
ac_cpp_err=yes
|
||||||
|
fi
|
||||||
|
if test -z "$ac_cpp_err"; then
|
||||||
|
ac_header_preproc=yes
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
sed 's/^/| /' conftest.$ac_ext >&5
|
||||||
|
|
||||||
|
ac_header_preproc=no
|
||||||
|
fi
|
||||||
|
rm -f conftest.err conftest.$ac_ext
|
||||||
|
echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
|
||||||
|
echo "${ECHO_T}$ac_header_preproc" >&6
|
||||||
|
|
||||||
|
# So? What about this header?
|
||||||
|
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
|
||||||
|
yes:no: )
|
||||||
|
{ echo "$as_me:$LINENO: WARNING: libxml/parser.h: accepted by the compiler, rejected by the preprocessor!" >&5
|
||||||
|
echo "$as_me: WARNING: libxml/parser.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
|
||||||
|
{ echo "$as_me:$LINENO: WARNING: libxml/parser.h: proceeding with the compiler's result" >&5
|
||||||
|
echo "$as_me: WARNING: libxml/parser.h: proceeding with the compiler's result" >&2;}
|
||||||
|
ac_header_preproc=yes
|
||||||
|
;;
|
||||||
|
no:yes:* )
|
||||||
|
{ echo "$as_me:$LINENO: WARNING: libxml/parser.h: present but cannot be compiled" >&5
|
||||||
|
echo "$as_me: WARNING: libxml/parser.h: present but cannot be compiled" >&2;}
|
||||||
|
{ echo "$as_me:$LINENO: WARNING: libxml/parser.h: check for missing prerequisite headers?" >&5
|
||||||
|
echo "$as_me: WARNING: libxml/parser.h: check for missing prerequisite headers?" >&2;}
|
||||||
|
{ echo "$as_me:$LINENO: WARNING: libxml/parser.h: see the Autoconf documentation" >&5
|
||||||
|
echo "$as_me: WARNING: libxml/parser.h: see the Autoconf documentation" >&2;}
|
||||||
|
{ echo "$as_me:$LINENO: WARNING: libxml/parser.h: section \"Present But Cannot Be Compiled\"" >&5
|
||||||
|
echo "$as_me: WARNING: libxml/parser.h: section \"Present But Cannot Be Compiled\"" >&2;}
|
||||||
|
{ echo "$as_me:$LINENO: WARNING: libxml/parser.h: proceeding with the preprocessor's result" >&5
|
||||||
|
echo "$as_me: WARNING: libxml/parser.h: proceeding with the preprocessor's result" >&2;}
|
||||||
|
{ echo "$as_me:$LINENO: WARNING: libxml/parser.h: in the future, the compiler will take precedence" >&5
|
||||||
|
echo "$as_me: WARNING: libxml/parser.h: in the future, the compiler will take precedence" >&2;}
|
||||||
|
(
|
||||||
|
cat <<\_ASBOX
|
||||||
|
## ---------------------------------------- ##
|
||||||
|
## Report this to pgsql-bugs@postgresql.org ##
|
||||||
|
## ---------------------------------------- ##
|
||||||
|
_ASBOX
|
||||||
|
) |
|
||||||
|
sed "s/^/$as_me: WARNING: /" >&2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "$as_me:$LINENO: checking for libxml/parser.h" >&5
|
||||||
|
echo $ECHO_N "checking for libxml/parser.h... $ECHO_C" >&6
|
||||||
|
if test "${ac_cv_header_libxml_parser_h+set}" = set; then
|
||||||
|
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||||
|
else
|
||||||
|
ac_cv_header_libxml_parser_h=$ac_header_preproc
|
||||||
|
fi
|
||||||
|
echo "$as_me:$LINENO: result: $ac_cv_header_libxml_parser_h" >&5
|
||||||
|
echo "${ECHO_T}$ac_cv_header_libxml_parser_h" >&6
|
||||||
|
|
||||||
|
fi
|
||||||
|
if test $ac_cv_header_libxml_parser_h = yes; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
{ { echo "$as_me:$LINENO: error: header file <libxml/parser.h> is required for XML support" >&5
|
||||||
|
echo "$as_me: error: header file <libxml/parser.h> is required for XML support" >&2;}
|
||||||
|
{ (exit 1); exit 1; }; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$with_ldap" = yes ; then
|
if test "$with_ldap" = yes ; then
|
||||||
|
17
configure.in
17
configure.in
@ -1,5 +1,5 @@
|
|||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
dnl $PostgreSQL: pgsql/configure.in,v 1.492 2006/12/14 21:49:54 tgl Exp $
|
dnl $PostgreSQL: pgsql/configure.in,v 1.493 2006/12/21 16:05:12 petere Exp $
|
||||||
dnl
|
dnl
|
||||||
dnl Developers, please strive to achieve this order:
|
dnl Developers, please strive to achieve this order:
|
||||||
dnl
|
dnl
|
||||||
@ -531,6 +531,13 @@ PGAC_ARG_BOOL(with, libedit-preferred, no,
|
|||||||
[ --with-libedit-preferred prefer BSD Libedit over GNU Readline])
|
[ --with-libedit-preferred prefer BSD Libedit over GNU Readline])
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# XML
|
||||||
|
#
|
||||||
|
PGAC_ARG_BOOL(with, libxml, no, [ --with-libxml build with XML support],
|
||||||
|
[AC_DEFINE([USE_LIBXML], 1, [Define to 1 to build with XML support. (--with-libxml)])])
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Zlib
|
# Zlib
|
||||||
#
|
#
|
||||||
@ -716,6 +723,10 @@ if test "$with_pam" = yes ; then
|
|||||||
AC_CHECK_LIB(pam, pam_start, [], [AC_MSG_ERROR([library 'pam' is required for PAM])])
|
AC_CHECK_LIB(pam, pam_start, [], [AC_MSG_ERROR([library 'pam' is required for PAM])])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$with_libxml" = yes ; then
|
||||||
|
AC_CHECK_LIB(xml2, xmlInitParser, [], [AC_MSG_ERROR([library 'xml2' is required for XML support])])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Header files
|
## Header files
|
||||||
@ -791,6 +802,10 @@ if test "$with_pam" = yes ; then
|
|||||||
[AC_MSG_ERROR([header file <security/pam_appl.h> or <pam/pam_appl.h> is required for PAM.])])])
|
[AC_MSG_ERROR([header file <security/pam_appl.h> or <pam/pam_appl.h> is required for PAM.])])])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$with_libxml" = yes ; then
|
||||||
|
AC_CHECK_HEADER(libxml/parser.h, [], [AC_MSG_ERROR([header file <libxml/parser.h> is required for XML support])])
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$with_ldap" = yes ; then
|
if test "$with_ldap" = yes ; then
|
||||||
if test "$PORTNAME" != "win32"; then
|
if test "$PORTNAME" != "win32"; then
|
||||||
AC_CHECK_HEADERS(ldap.h, [],
|
AC_CHECK_HEADERS(ldap.h, [],
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.181 2006/11/23 04:27:33 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.182 2006/12/21 16:05:12 petere Exp $ -->
|
||||||
|
|
||||||
<chapter id="datatype">
|
<chapter id="datatype">
|
||||||
<title id="datatype-title">Data Types</title>
|
<title id="datatype-title">Data Types</title>
|
||||||
@ -233,6 +233,12 @@
|
|||||||
<entry><type>timestamptz</type></entry>
|
<entry><type>timestamptz</type></entry>
|
||||||
<entry>date and time, including time zone</entry>
|
<entry>date and time, including time zone</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><type>xml</type></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>XML data</entry>
|
||||||
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
@ -248,7 +254,8 @@
|
|||||||
precision</type>, <type>integer</type>, <type>interval</type>,
|
precision</type>, <type>integer</type>, <type>interval</type>,
|
||||||
<type>numeric</type>, <type>decimal</type>, <type>real</type>,
|
<type>numeric</type>, <type>decimal</type>, <type>real</type>,
|
||||||
<type>smallint</type>, <type>time</type> (with or without time zone),
|
<type>smallint</type>, <type>time</type> (with or without time zone),
|
||||||
<type>timestamp</type> (with or without time zone).
|
<type>timestamp</type> (with or without time zone),
|
||||||
|
<type>xml</type>.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
@ -3358,12 +3365,21 @@ SELECT * FROM pg_attribute
|
|||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="datatype-xml">
|
<sect1 id="datatype-xml">
|
||||||
<title><acronym>XML</> Document Support</title>
|
<title><acronym>XML</> Type</title>
|
||||||
|
|
||||||
<indexterm zone="datatype">
|
<indexterm zone="datatype-xml">
|
||||||
<primary>xml</primary>
|
<primary>XML</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The data type <type>xml</type> can be used to store XML data. Its
|
||||||
|
advantage over storing XML data in, say, a text field is that it
|
||||||
|
checks the input values for well-formedness, and there are support
|
||||||
|
functions to perform type-safe operations on it; see <xref
|
||||||
|
linkend="functions-xml">. Currently, there is no support for
|
||||||
|
validation against a specific <acronym>XML</> schema.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<acronym>XML</> (Extensible Markup Language) support is not one
|
<acronym>XML</> (Extensible Markup Language) support is not one
|
||||||
capability, but a variety of features supported by a database
|
capability, but a variety of features supported by a database
|
||||||
@ -3378,22 +3394,6 @@ SELECT * FROM pg_attribute
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>Storage</term>
|
|
||||||
<listitem>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
PostgreSQL does not have a specialized <acronym>XML</> data type.
|
|
||||||
Users should store <acronym>XML</> documents in ordinary
|
|
||||||
<type>TEXT</> fields. If you need the document split apart into
|
|
||||||
its component parts so each element is stored separately, you must
|
|
||||||
use a middle-ware solution to do that, but once done, the data
|
|
||||||
becomes relational and has to be processed accordingly.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>Import/Export</term>
|
<term>Import/Export</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -3408,21 +3408,6 @@ SELECT * FROM pg_attribute
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>Validation</term>
|
|
||||||
<listitem>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<filename>/contrib/xml2</> has a function called
|
|
||||||
<function>xml_is_well_formed()</> that can be used in a <literal>CHECK</>
|
|
||||||
constraint to enforce that a field contains well-formed <acronym>XML</>.
|
|
||||||
It does not support validation against a specific <acronym>XML</>
|
|
||||||
schema. A server-side language with <acronym>XML</> capabilities
|
|
||||||
could be used to do schema-specific <acronym>XML</> checks.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>Indexing</term>
|
<term>Indexing</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -3438,20 +3423,6 @@ SELECT * FROM pg_attribute
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>Modification</term>
|
|
||||||
<listitem>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
If an <command>UPDATE</> does not modify an <acronym>XML</> field,
|
|
||||||
the <acronym>XML</> data is shared between the old and new rows.
|
|
||||||
However, if the <command>UPDATE</> modifies an <acronym>XML</>
|
|
||||||
field, a full modified copy of the <acronym>XML</> field must be
|
|
||||||
created internally.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>Searching</term>
|
<term>Searching</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -3487,19 +3458,6 @@ SELECT * FROM pg_attribute
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>Missing Features</term>
|
|
||||||
<listitem>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Missing features include XQuery, SQL/XML syntax (ISO/IEC
|
|
||||||
9075-14), and an <acronym>XML</> data type optimized for
|
|
||||||
<acronym>XML</> storage.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.347 2006/11/25 00:38:53 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.348 2006/12/21 16:05:12 petere Exp $ -->
|
||||||
|
|
||||||
<chapter id="functions">
|
<chapter id="functions">
|
||||||
<title>Functions and Operators</title>
|
<title>Functions and Operators</title>
|
||||||
@ -10741,4 +10741,113 @@ SELECT (pg_stat_file('filename')).modification;
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
<sect1 id="functions-xml">
|
||||||
|
<title>XML Functions</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The functions and function-like expressions described in this
|
||||||
|
section operate on values of type <type>xml</type>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title><literal>xmlcomment</literal></title>
|
||||||
|
|
||||||
|
<indexterm>
|
||||||
|
<primary>xmlcomment</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<synopsis>
|
||||||
|
<function>xmlcomment</function>(<replaceable>text</replaceable>)
|
||||||
|
</synopsis>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Creates an XML comment.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title><literal>xmlconcat</literal></title>
|
||||||
|
|
||||||
|
<indexterm>
|
||||||
|
<primary>xmlconcat</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<synopsis>
|
||||||
|
<function>xmlconcat</function>(<replaceable>xml</replaceable><optional>, xml, ...</optional>)
|
||||||
|
</synopsis>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Combines a list of individual XML values to create a
|
||||||
|
single value containing an XML forest.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title><literal>xmlelement</literal></title>
|
||||||
|
|
||||||
|
<indexterm>
|
||||||
|
<primary>xmlelement</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<synopsis>
|
||||||
|
<function>xmlelement</function>(name <replaceable>name</replaceable><optional>, xmlattribytes(<replaceable>value</replaceable> <optional>AS <replaceable>label</replaceable></optional><optional>, ... </optional>)</optional>
|
||||||
|
<optional><replaceable>, content, ...</replaceable></optional>)
|
||||||
|
</synopsis>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Creates an XML element, allowing the name to be specified.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title><literal>xmlforest</literal></title>
|
||||||
|
|
||||||
|
<indexterm>
|
||||||
|
<primary>xmlforest</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<synopsis>
|
||||||
|
<function>xmlforest</function>(<replaceable>value</replaceable> <optional>AS <replaceable>label</replaceable></optional><optional>, ...</optional>)
|
||||||
|
</synopsis>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Creates XML elements from columns, using the name of each
|
||||||
|
column as the name of the corresponding element.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title><literal>xmlpi</literal></title>
|
||||||
|
|
||||||
|
<indexterm>
|
||||||
|
<primary>xmlpi</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<synopsis>
|
||||||
|
<function>xmlpi</function>(name <replaceable>target</replaceable> <optional>, <replaceable>content</replaceable></optional>)
|
||||||
|
</synopsis>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Creates an XML processing instruction.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title><literal>xmlroot</literal></title>
|
||||||
|
|
||||||
|
<indexterm>
|
||||||
|
<primary>xmlroot</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<synopsis>
|
||||||
|
<function>xmlroot</function>(<replaceable>xml</replaceable>, version <replaceable>text</replaceable> <optional>, standalone yes|no|no value</optional>)
|
||||||
|
</synopsis>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Creates the root node of an XML document.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/installation.sgml,v 1.268 2006/12/02 09:29:51 petere Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/installation.sgml,v 1.269 2006/12/21 16:05:13 petere Exp $ -->
|
||||||
|
|
||||||
<chapter id="installation">
|
<chapter id="installation">
|
||||||
<title><![%standalone-include[<productname>PostgreSQL</>]]>
|
<title><![%standalone-include[<productname>PostgreSQL</>]]>
|
||||||
@ -905,6 +905,15 @@ su - postgres
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--with-libxml</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Build with libxml, required for SQL/XML support.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--enable-integer-datetimes</option></term>
|
<term><option>--enable-integer-datetimes</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.199 2006/11/17 16:46:27 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.200 2006/12/21 16:05:13 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -52,6 +52,7 @@
|
|||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/typcache.h"
|
#include "utils/typcache.h"
|
||||||
|
#include "utils/xml.h"
|
||||||
|
|
||||||
|
|
||||||
/* static function decls */
|
/* static function decls */
|
||||||
@ -119,6 +120,8 @@ static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
|
|||||||
static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
|
static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
|
||||||
ExprContext *econtext,
|
ExprContext *econtext,
|
||||||
bool *isNull, ExprDoneCond *isDone);
|
bool *isNull, ExprDoneCond *isDone);
|
||||||
|
static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
|
||||||
|
bool *isNull, ExprDoneCond *isDone);
|
||||||
static Datum ExecEvalNullTest(NullTestState *nstate,
|
static Datum ExecEvalNullTest(NullTestState *nstate,
|
||||||
ExprContext *econtext,
|
ExprContext *econtext,
|
||||||
bool *isNull, ExprDoneCond *isDone);
|
bool *isNull, ExprDoneCond *isDone);
|
||||||
@ -2878,6 +2881,120 @@ ExecEvalBooleanTest(GenericExprState *bstate,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------
|
||||||
|
* ExecEvalXml
|
||||||
|
* ----------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Datum
|
||||||
|
ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
|
||||||
|
bool *isNull, ExprDoneCond *isDone)
|
||||||
|
{
|
||||||
|
StringInfoData buf;
|
||||||
|
bool isnull;
|
||||||
|
ListCell *arg;
|
||||||
|
text *result = NULL;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
initStringInfo(&buf);
|
||||||
|
|
||||||
|
*isNull = false;
|
||||||
|
|
||||||
|
if (isDone)
|
||||||
|
*isDone = ExprSingleResult;
|
||||||
|
|
||||||
|
switch (xmlExpr->op)
|
||||||
|
{
|
||||||
|
case IS_XMLCONCAT:
|
||||||
|
*isNull = true;
|
||||||
|
|
||||||
|
foreach(arg, xmlExpr->args)
|
||||||
|
{
|
||||||
|
ExprState *e = (ExprState *) lfirst(arg);
|
||||||
|
Datum value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
|
||||||
|
if (!isnull)
|
||||||
|
{
|
||||||
|
appendStringInfoString(&buf, DatumGetCString(OidFunctionCall1(xmlExpr->arg_typeout, value)));
|
||||||
|
*isNull = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_XMLELEMENT:
|
||||||
|
{
|
||||||
|
int state = 0, i = 0;
|
||||||
|
appendStringInfo(&buf, "<%s", xmlExpr->name);
|
||||||
|
foreach(arg, xmlExpr->named_args)
|
||||||
|
{
|
||||||
|
GenericExprState *gstate = (GenericExprState *) lfirst(arg);
|
||||||
|
Datum value = ExecEvalExpr(gstate->arg, econtext, &isnull, NULL);
|
||||||
|
if (!isnull)
|
||||||
|
{
|
||||||
|
char *outstr = DatumGetCString(OidFunctionCall1(xmlExpr->named_args_tcache[i], value));
|
||||||
|
appendStringInfo(&buf, " %s=\"%s\"", xmlExpr->named_args_ncache[i], outstr);
|
||||||
|
pfree(outstr);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (xmlExpr->args)
|
||||||
|
{
|
||||||
|
ExprState *expr = linitial(xmlExpr->args);
|
||||||
|
Datum value = ExecEvalExpr(expr, econtext, &isnull, NULL);
|
||||||
|
|
||||||
|
if (!isnull)
|
||||||
|
{
|
||||||
|
char *outstr = DatumGetCString(OidFunctionCall1(xmlExpr->arg_typeout, value));
|
||||||
|
if (state == 0)
|
||||||
|
{
|
||||||
|
appendStringInfoChar(&buf, '>');
|
||||||
|
state = 1;
|
||||||
|
}
|
||||||
|
appendStringInfo(&buf, "%s", outstr);
|
||||||
|
pfree(outstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == 0)
|
||||||
|
appendStringInfo(&buf, "/>");
|
||||||
|
else if (state == 1)
|
||||||
|
appendStringInfo(&buf, "</%s>", xmlExpr->name);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_XMLFOREST:
|
||||||
|
{
|
||||||
|
/* only if all argumets are null returns null */
|
||||||
|
int i = 0;
|
||||||
|
*isNull = true;
|
||||||
|
foreach(arg, xmlExpr->named_args)
|
||||||
|
{
|
||||||
|
GenericExprState *gstate = (GenericExprState *) lfirst(arg);
|
||||||
|
Datum value = ExecEvalExpr(gstate->arg, econtext, &isnull, NULL);
|
||||||
|
if (!isnull)
|
||||||
|
{
|
||||||
|
char *outstr = DatumGetCString(OidFunctionCall1(xmlExpr->named_args_tcache[i], value));
|
||||||
|
appendStringInfo(&buf, "<%s>%s</%s>", xmlExpr->named_args_ncache[i], outstr, xmlExpr->named_args_ncache[i]);
|
||||||
|
pfree(outstr);
|
||||||
|
*isNull = false;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = buf.len + VARHDRSZ;
|
||||||
|
result = palloc(len);
|
||||||
|
VARATT_SIZEP(result) = len;
|
||||||
|
memcpy(VARDATA(result), buf.data, buf.len);
|
||||||
|
pfree(buf.data);
|
||||||
|
PG_RETURN_TEXT_P(result);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ExecEvalCoerceToDomain
|
* ExecEvalCoerceToDomain
|
||||||
*
|
*
|
||||||
@ -3668,6 +3785,64 @@ ExecInitExpr(Expr *node, PlanState *parent)
|
|||||||
state = (ExprState *) mstate;
|
state = (ExprState *) mstate;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
{
|
||||||
|
List *outlist;
|
||||||
|
ListCell *arg;
|
||||||
|
XmlExpr *xexpr = (XmlExpr *) node;
|
||||||
|
XmlExprState *xstate = makeNode(XmlExprState);
|
||||||
|
int i = 0;
|
||||||
|
Oid typeout;
|
||||||
|
|
||||||
|
xstate->name = xexpr->name;
|
||||||
|
|
||||||
|
xstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalXml;
|
||||||
|
xstate->op = xexpr->op;
|
||||||
|
|
||||||
|
outlist = NIL;
|
||||||
|
if (xexpr->named_args)
|
||||||
|
{
|
||||||
|
xstate->named_args_tcache = (Oid *) palloc(list_length(xexpr->named_args) * sizeof(int));
|
||||||
|
xstate->named_args_ncache = (char **) palloc(list_length(xexpr->named_args) * sizeof(char *));
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
foreach(arg, xexpr->named_args)
|
||||||
|
{
|
||||||
|
bool tpisvarlena;
|
||||||
|
Expr *e = (Expr *) lfirst(arg);
|
||||||
|
ExprState *estate = ExecInitExpr(e, parent);
|
||||||
|
TargetEntry *tle;
|
||||||
|
outlist = lappend(outlist, estate);
|
||||||
|
tle = (TargetEntry *) ((GenericExprState *) estate)->xprstate.expr;
|
||||||
|
getTypeOutputInfo(exprType((Node *)tle->expr), &typeout, &tpisvarlena);
|
||||||
|
xstate->named_args_ncache[i] = tle->resname;
|
||||||
|
xstate->named_args_tcache[i] = typeout;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xstate->named_args_tcache = NULL;
|
||||||
|
xstate->named_args_ncache = NULL;
|
||||||
|
}
|
||||||
|
xstate->named_args = outlist;
|
||||||
|
|
||||||
|
outlist = NIL;
|
||||||
|
foreach(arg, xexpr->args)
|
||||||
|
{
|
||||||
|
bool tpisvarlena;
|
||||||
|
ExprState *estate;
|
||||||
|
Expr *e = (Expr *) lfirst(arg);
|
||||||
|
getTypeOutputInfo(exprType((Node *)e), &typeout, &tpisvarlena);
|
||||||
|
estate = ExecInitExpr(e, parent);
|
||||||
|
outlist = lappend(outlist, estate);
|
||||||
|
}
|
||||||
|
xstate->arg_typeout = typeout;
|
||||||
|
xstate->args = outlist;
|
||||||
|
|
||||||
|
state = (ExprState *) xstate;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case T_NullIfExpr:
|
case T_NullIfExpr:
|
||||||
{
|
{
|
||||||
NullIfExpr *nullifexpr = (NullIfExpr *) node;
|
NullIfExpr *nullifexpr = (NullIfExpr *) node;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.354 2006/12/10 22:13:26 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.355 2006/12/21 16:05:13 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1136,6 +1136,22 @@ _copyBooleanTest(BooleanTest *from)
|
|||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _copyXmlExpr
|
||||||
|
*/
|
||||||
|
static XmlExpr *
|
||||||
|
_copyXmlExpr(XmlExpr *from)
|
||||||
|
{
|
||||||
|
XmlExpr *newnode = makeNode(XmlExpr);
|
||||||
|
|
||||||
|
COPY_SCALAR_FIELD(op);
|
||||||
|
COPY_STRING_FIELD(name);
|
||||||
|
COPY_NODE_FIELD(named_args);
|
||||||
|
COPY_NODE_FIELD(args);
|
||||||
|
|
||||||
|
return newnode;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _copyCoerceToDomain
|
* _copyCoerceToDomain
|
||||||
*/
|
*/
|
||||||
@ -2966,6 +2982,9 @@ copyObject(void *from)
|
|||||||
case T_BooleanTest:
|
case T_BooleanTest:
|
||||||
retval = _copyBooleanTest(from);
|
retval = _copyBooleanTest(from);
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
retval = _copyXmlExpr(from);
|
||||||
|
break;
|
||||||
case T_CoerceToDomain:
|
case T_CoerceToDomain:
|
||||||
retval = _copyCoerceToDomain(from);
|
retval = _copyCoerceToDomain(from);
|
||||||
break;
|
break;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.288 2006/12/10 22:13:26 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.289 2006/12/21 16:05:13 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -495,6 +495,17 @@ _equalBooleanTest(BooleanTest *a, BooleanTest *b)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_equalXmlExpr(XmlExpr *a, XmlExpr *b)
|
||||||
|
{
|
||||||
|
COMPARE_SCALAR_FIELD(op);
|
||||||
|
COMPARE_STRING_FIELD(name);
|
||||||
|
COMPARE_NODE_FIELD(named_args);
|
||||||
|
COMPARE_NODE_FIELD(args);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_equalCoerceToDomain(CoerceToDomain *a, CoerceToDomain *b)
|
_equalCoerceToDomain(CoerceToDomain *a, CoerceToDomain *b)
|
||||||
{
|
{
|
||||||
@ -1968,6 +1979,9 @@ equal(void *a, void *b)
|
|||||||
case T_BooleanTest:
|
case T_BooleanTest:
|
||||||
retval = _equalBooleanTest(a, b);
|
retval = _equalBooleanTest(a, b);
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
retval = _equalXmlExpr(a, b);
|
||||||
|
break;
|
||||||
case T_CoerceToDomain:
|
case T_CoerceToDomain:
|
||||||
retval = _equalCoerceToDomain(a, b);
|
retval = _equalCoerceToDomain(a, b);
|
||||||
break;
|
break;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.286 2006/12/10 22:13:26 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.287 2006/12/21 16:05:13 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Every node type that can appear in stored rules' parsetrees *must*
|
* Every node type that can appear in stored rules' parsetrees *must*
|
||||||
@ -920,6 +920,17 @@ _outBooleanTest(StringInfo str, BooleanTest *node)
|
|||||||
WRITE_ENUM_FIELD(booltesttype, BoolTestType);
|
WRITE_ENUM_FIELD(booltesttype, BoolTestType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_outXmlExpr(StringInfo str, XmlExpr *node)
|
||||||
|
{
|
||||||
|
WRITE_NODE_TYPE("XMLEXPR");
|
||||||
|
|
||||||
|
WRITE_ENUM_FIELD(op, XmlExprOp);
|
||||||
|
WRITE_STRING_FIELD(name);
|
||||||
|
WRITE_NODE_FIELD(named_args);
|
||||||
|
WRITE_NODE_FIELD(args);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_outCoerceToDomain(StringInfo str, CoerceToDomain *node)
|
_outCoerceToDomain(StringInfo str, CoerceToDomain *node)
|
||||||
{
|
{
|
||||||
@ -2019,6 +2030,9 @@ _outNode(StringInfo str, void *obj)
|
|||||||
case T_BooleanTest:
|
case T_BooleanTest:
|
||||||
_outBooleanTest(str, obj);
|
_outBooleanTest(str, obj);
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
_outXmlExpr(str, obj);
|
||||||
|
break;
|
||||||
case T_CoerceToDomain:
|
case T_CoerceToDomain:
|
||||||
_outCoerceToDomain(str, obj);
|
_outCoerceToDomain(str, obj);
|
||||||
break;
|
break;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.196 2006/12/10 22:13:26 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.197 2006/12/21 16:05:13 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Path and Plan nodes do not have any readfuncs support, because we
|
* Path and Plan nodes do not have any readfuncs support, because we
|
||||||
@ -764,6 +764,22 @@ _readBooleanTest(void)
|
|||||||
READ_DONE();
|
READ_DONE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _readXmlExpr
|
||||||
|
*/
|
||||||
|
static XmlExpr *
|
||||||
|
_readXmlExpr(void)
|
||||||
|
{
|
||||||
|
READ_LOCALS(XmlExpr);
|
||||||
|
|
||||||
|
READ_ENUM_FIELD(op, XmlExprOp);
|
||||||
|
READ_STRING_FIELD(name);
|
||||||
|
READ_NODE_FIELD(named_args);
|
||||||
|
READ_NODE_FIELD(args);
|
||||||
|
|
||||||
|
READ_DONE();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _readCoerceToDomain
|
* _readCoerceToDomain
|
||||||
*/
|
*/
|
||||||
@ -1014,6 +1030,8 @@ parseNodeString(void)
|
|||||||
return_value = _readNullTest();
|
return_value = _readNullTest();
|
||||||
else if (MATCH("BOOLEANTEST", 11))
|
else if (MATCH("BOOLEANTEST", 11))
|
||||||
return_value = _readBooleanTest();
|
return_value = _readBooleanTest();
|
||||||
|
else if (MATCH("XMLEXPR", 7))
|
||||||
|
return_value = _readXmlExpr();
|
||||||
else if (MATCH("COERCETODOMAIN", 14))
|
else if (MATCH("COERCETODOMAIN", 14))
|
||||||
return_value = _readCoerceToDomain();
|
return_value = _readCoerceToDomain();
|
||||||
else if (MATCH("COERCETODOMAINVALUE", 19))
|
else if (MATCH("COERCETODOMAINVALUE", 19))
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.223 2006/10/25 22:11:32 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.224 2006/12/21 16:05:13 petere Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -559,6 +559,8 @@ expression_returns_set_walker(Node *node, void *context)
|
|||||||
return false;
|
return false;
|
||||||
if (IsA(node, NullIfExpr))
|
if (IsA(node, NullIfExpr))
|
||||||
return false;
|
return false;
|
||||||
|
if (IsA(node, XmlExpr))
|
||||||
|
return false;
|
||||||
|
|
||||||
return expression_tree_walker(node, expression_returns_set_walker,
|
return expression_tree_walker(node, expression_returns_set_walker,
|
||||||
context);
|
context);
|
||||||
@ -876,6 +878,8 @@ contain_nonstrict_functions_walker(Node *node, void *context)
|
|||||||
return true;
|
return true;
|
||||||
if (IsA(node, BooleanTest))
|
if (IsA(node, BooleanTest))
|
||||||
return true;
|
return true;
|
||||||
|
if (IsA(node, XmlExpr))
|
||||||
|
return true;
|
||||||
return expression_tree_walker(node, contain_nonstrict_functions_walker,
|
return expression_tree_walker(node, contain_nonstrict_functions_walker,
|
||||||
context);
|
context);
|
||||||
}
|
}
|
||||||
@ -3334,6 +3338,16 @@ expression_tree_walker(Node *node,
|
|||||||
return walker(((NullTest *) node)->arg, context);
|
return walker(((NullTest *) node)->arg, context);
|
||||||
case T_BooleanTest:
|
case T_BooleanTest:
|
||||||
return walker(((BooleanTest *) node)->arg, context);
|
return walker(((BooleanTest *) node)->arg, context);
|
||||||
|
case T_XmlExpr:
|
||||||
|
{
|
||||||
|
XmlExpr *xexpr = (XmlExpr *) node;
|
||||||
|
|
||||||
|
if (walker(xexpr->named_args, context))
|
||||||
|
return true;
|
||||||
|
if (walker(xexpr->args, context))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case T_CoerceToDomain:
|
case T_CoerceToDomain:
|
||||||
return walker(((CoerceToDomain *) node)->arg, context);
|
return walker(((CoerceToDomain *) node)->arg, context);
|
||||||
case T_TargetEntry:
|
case T_TargetEntry:
|
||||||
@ -3857,6 +3871,17 @@ expression_tree_mutator(Node *node,
|
|||||||
return (Node *) newnode;
|
return (Node *) newnode;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
{
|
||||||
|
XmlExpr *xexpr = (XmlExpr *) node;
|
||||||
|
XmlExpr *newnode;
|
||||||
|
|
||||||
|
FLATCOPY(newnode, xexpr, XmlExpr);
|
||||||
|
MUTATE(newnode->named_args, xexpr->named_args, List *);
|
||||||
|
MUTATE(newnode->args, xexpr->args, List *);
|
||||||
|
return (Node *) newnode;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case T_NullIfExpr:
|
case T_NullIfExpr:
|
||||||
{
|
{
|
||||||
NullIfExpr *expr = (NullIfExpr *) node;
|
NullIfExpr *expr = (NullIfExpr *) node;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.568 2006/11/05 22:42:09 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.569 2006/12/21 16:05:14 petere Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -106,6 +106,7 @@ static void insertSelectOptions(SelectStmt *stmt,
|
|||||||
static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
|
static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
|
||||||
static Node *doNegate(Node *n, int location);
|
static Node *doNegate(Node *n, int location);
|
||||||
static void doNegateFloat(Value *v);
|
static void doNegateFloat(Value *v);
|
||||||
|
static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args);
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -345,6 +346,11 @@ static void doNegateFloat(Value *v);
|
|||||||
%type <str> OptTableSpace OptConsTableSpace OptTableSpaceOwner
|
%type <str> OptTableSpace OptConsTableSpace OptTableSpaceOwner
|
||||||
%type <list> opt_check_option
|
%type <list> opt_check_option
|
||||||
|
|
||||||
|
%type <target> xml_attribute_el
|
||||||
|
%type <list> xml_attribute_list xml_attributes
|
||||||
|
%type <node> xml_root_version
|
||||||
|
%type <ival> opt_xml_root_standalone document_or_content xml_whitespace_option
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If you make any token changes, update the keyword table in
|
* If you make any token changes, update the keyword table in
|
||||||
@ -365,13 +371,13 @@ static void doNegateFloat(Value *v);
|
|||||||
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
|
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
|
||||||
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
|
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
|
||||||
COMMITTED CONCURRENTLY CONNECTION CONSTRAINT CONSTRAINTS
|
COMMITTED CONCURRENTLY CONNECTION CONSTRAINT CONSTRAINTS
|
||||||
CONVERSION_P CONVERT COPY CREATE CREATEDB
|
CONTENT CONVERSION_P CONVERT COPY CREATE CREATEDB
|
||||||
CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_ROLE CURRENT_TIME
|
CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_ROLE CURRENT_TIME
|
||||||
CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
|
CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
|
||||||
|
|
||||||
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
|
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
|
||||||
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
|
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
|
||||||
DESC DISABLE_P DISTINCT DO DOMAIN_P DOUBLE_P DROP
|
DESC DISABLE_P DISTINCT DO DOCUMENT DOMAIN_P DOUBLE_P DROP
|
||||||
|
|
||||||
EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
|
EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
|
||||||
EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
|
EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
|
||||||
@ -398,7 +404,7 @@ static void doNegateFloat(Value *v);
|
|||||||
|
|
||||||
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
|
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
|
||||||
|
|
||||||
NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
|
NAME NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
|
||||||
NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
|
NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
|
||||||
NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NUMERIC
|
NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NUMERIC
|
||||||
|
|
||||||
@ -417,8 +423,8 @@ static void doNegateFloat(Value *v);
|
|||||||
|
|
||||||
SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
|
SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
|
||||||
SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
|
SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
|
||||||
SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT
|
SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE START STATEMENT
|
||||||
STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SUPERUSER_P SYMMETRIC
|
STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP SUBSTRING SUPERUSER_P SYMMETRIC
|
||||||
SYSID SYSTEM_P
|
SYSID SYSTEM_P
|
||||||
|
|
||||||
TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP
|
TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP
|
||||||
@ -428,12 +434,15 @@ static void doNegateFloat(Value *v);
|
|||||||
UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
|
UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
|
||||||
UPDATE USER USING
|
UPDATE USER USING
|
||||||
|
|
||||||
VACUUM VALID VALIDATOR VALUES VARCHAR VARYING
|
VACUUM VALID VALIDATOR VALUE VALUES VARCHAR VARYING
|
||||||
VERBOSE VIEW VOLATILE
|
VERBOSE VERSION VIEW VOLATILE
|
||||||
|
|
||||||
WHEN WHERE WITH WITHOUT WORK WRITE
|
WHEN WHERE WHITESPACE WITH WITHOUT WORK WRITE
|
||||||
|
|
||||||
YEAR_P
|
XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
|
||||||
|
XMLPI XMLROOT XMLSERIALIZE
|
||||||
|
|
||||||
|
YEAR_P YES
|
||||||
|
|
||||||
ZONE
|
ZONE
|
||||||
|
|
||||||
@ -484,6 +493,7 @@ static void doNegateFloat(Value *v);
|
|||||||
* left-associativity among the JOIN rules themselves.
|
* left-associativity among the JOIN rules themselves.
|
||||||
*/
|
*/
|
||||||
%left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
|
%left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
|
||||||
|
%right PRESERVE STRIP
|
||||||
%%
|
%%
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -7868,6 +7878,146 @@ func_expr: func_name '(' ')'
|
|||||||
v->op = IS_LEAST;
|
v->op = IS_LEAST;
|
||||||
$$ = (Node *)v;
|
$$ = (Node *)v;
|
||||||
}
|
}
|
||||||
|
| XMLCONCAT '(' expr_list ')'
|
||||||
|
{
|
||||||
|
$$ = makeXmlExpr(IS_XMLCONCAT, NULL, NULL, $3);
|
||||||
|
}
|
||||||
|
| XMLELEMENT '(' NAME ColLabel ')'
|
||||||
|
{
|
||||||
|
$$ = makeXmlExpr(IS_XMLELEMENT, $4, NULL, NULL);
|
||||||
|
}
|
||||||
|
| XMLELEMENT '(' NAME ColLabel ',' xml_attributes ')'
|
||||||
|
{
|
||||||
|
$$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, NULL);
|
||||||
|
}
|
||||||
|
| XMLELEMENT '(' NAME ColLabel ',' expr_list ')'
|
||||||
|
{
|
||||||
|
$$ = makeXmlExpr(IS_XMLELEMENT, $4, NULL, $6);
|
||||||
|
}
|
||||||
|
| XMLELEMENT '(' NAME ColLabel ',' xml_attributes ',' expr_list ')'
|
||||||
|
{
|
||||||
|
$$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, $8);
|
||||||
|
}
|
||||||
|
| XMLFOREST '(' xml_attribute_list ')'
|
||||||
|
{
|
||||||
|
$$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NULL);
|
||||||
|
}
|
||||||
|
| XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
|
||||||
|
{
|
||||||
|
FuncCall *n = makeNode(FuncCall);
|
||||||
|
n->funcname = SystemFuncName("xmlparse");
|
||||||
|
n->args = list_make3(makeBoolAConst($3 == DOCUMENT), $4, makeBoolAConst($5 == PRESERVE));
|
||||||
|
n->agg_star = FALSE;
|
||||||
|
n->agg_distinct = FALSE;
|
||||||
|
n->location = @1;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
| XMLPI '(' NAME ColLabel ')'
|
||||||
|
{
|
||||||
|
FuncCall *n = makeNode(FuncCall);
|
||||||
|
n->funcname = SystemFuncName("xmlpi");
|
||||||
|
n->args = list_make1(makeStringConst($4, NULL));
|
||||||
|
n->agg_star = FALSE;
|
||||||
|
n->agg_distinct = FALSE;
|
||||||
|
n->location = @1;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
| XMLPI '(' NAME ColLabel ',' a_expr ')'
|
||||||
|
{
|
||||||
|
FuncCall *n = makeNode(FuncCall);
|
||||||
|
n->funcname = SystemFuncName("xmlpi");
|
||||||
|
n->args = list_make2(makeStringConst($4, NULL), $6);
|
||||||
|
n->agg_star = FALSE;
|
||||||
|
n->agg_distinct = FALSE;
|
||||||
|
n->location = @1;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
| XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')'
|
||||||
|
{
|
||||||
|
FuncCall *n = makeNode(FuncCall);
|
||||||
|
Node *ver;
|
||||||
|
A_Const *sa;
|
||||||
|
|
||||||
|
if ($5)
|
||||||
|
ver = $5;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
A_Const *val;
|
||||||
|
|
||||||
|
val = makeNode(A_Const);
|
||||||
|
val->val.type = T_Null;
|
||||||
|
ver = (Node *) val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($6)
|
||||||
|
sa = makeBoolAConst($6 == 1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sa = makeNode(A_Const);
|
||||||
|
sa->val.type = T_Null;
|
||||||
|
}
|
||||||
|
|
||||||
|
n->funcname = SystemFuncName("xmlroot");
|
||||||
|
n->args = list_make3($3, ver, sa);
|
||||||
|
n->agg_star = FALSE;
|
||||||
|
n->agg_distinct = FALSE;
|
||||||
|
n->location = @1;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
| XMLSERIALIZE '(' document_or_content a_expr AS Typename ')'
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* FIXME: This should be made distinguishable from
|
||||||
|
* CAST (for reverse compilation at least).
|
||||||
|
*/
|
||||||
|
$$ = makeTypeCast($4, $6);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SQL/XML support
|
||||||
|
*/
|
||||||
|
xml_root_version: VERSION a_expr { $$ = $2; }
|
||||||
|
| VERSION NO VALUE { $$ = NULL; }
|
||||||
|
;
|
||||||
|
|
||||||
|
opt_xml_root_standalone: ',' STANDALONE YES { $$ = 1; }
|
||||||
|
| ',' STANDALONE NO { $$ = -1; }
|
||||||
|
| ',' STANDALONE NO VALUE { $$ = 0; }
|
||||||
|
| /*EMPTY*/ { $$ = 0; }
|
||||||
|
;
|
||||||
|
|
||||||
|
xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
|
||||||
|
;
|
||||||
|
|
||||||
|
xml_attribute_list: xml_attribute_el { $$ = list_make1($1); }
|
||||||
|
| xml_attribute_list ',' xml_attribute_el { $$ = lappend($1, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
xml_attribute_el: a_expr AS ColLabel
|
||||||
|
{
|
||||||
|
$$ = makeNode(ResTarget);
|
||||||
|
$$->name = $3;
|
||||||
|
$$->indirection = NULL;
|
||||||
|
$$->val = (Node *) $1;
|
||||||
|
|
||||||
|
}
|
||||||
|
| a_expr
|
||||||
|
{
|
||||||
|
$$ = makeNode(ResTarget);
|
||||||
|
$$->name = NULL;
|
||||||
|
$$->indirection = NULL;
|
||||||
|
$$->val = (Node *) $1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
document_or_content: DOCUMENT { $$ = DOCUMENT; }
|
||||||
|
| CONTENT { $$ = CONTENT; }
|
||||||
|
;
|
||||||
|
|
||||||
|
xml_whitespace_option: PRESERVE WHITESPACE { $$ = PRESERVE; }
|
||||||
|
| STRIP WHITESPACE { $$ = STRIP; }
|
||||||
|
| /*EMPTY*/ { $$ = STRIP; }
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -8562,6 +8712,7 @@ unreserved_keyword:
|
|||||||
| CONCURRENTLY
|
| CONCURRENTLY
|
||||||
| CONNECTION
|
| CONNECTION
|
||||||
| CONSTRAINTS
|
| CONSTRAINTS
|
||||||
|
| CONTENT
|
||||||
| CONVERSION_P
|
| CONVERSION_P
|
||||||
| COPY
|
| COPY
|
||||||
| CREATEDB
|
| CREATEDB
|
||||||
@ -8581,6 +8732,7 @@ unreserved_keyword:
|
|||||||
| DELIMITER
|
| DELIMITER
|
||||||
| DELIMITERS
|
| DELIMITERS
|
||||||
| DISABLE_P
|
| DISABLE_P
|
||||||
|
| DOCUMENT
|
||||||
| DOMAIN_P
|
| DOMAIN_P
|
||||||
| DOUBLE_P
|
| DOUBLE_P
|
||||||
| DROP
|
| DROP
|
||||||
@ -8640,6 +8792,7 @@ unreserved_keyword:
|
|||||||
| MODE
|
| MODE
|
||||||
| MONTH_P
|
| MONTH_P
|
||||||
| MOVE
|
| MOVE
|
||||||
|
| NAME
|
||||||
| NAMES
|
| NAMES
|
||||||
| NEXT
|
| NEXT
|
||||||
| NO
|
| NO
|
||||||
@ -8700,12 +8853,14 @@ unreserved_keyword:
|
|||||||
| SHOW
|
| SHOW
|
||||||
| SIMPLE
|
| SIMPLE
|
||||||
| STABLE
|
| STABLE
|
||||||
|
| STANDALONE
|
||||||
| START
|
| START
|
||||||
| STATEMENT
|
| STATEMENT
|
||||||
| STATISTICS
|
| STATISTICS
|
||||||
| STDIN
|
| STDIN
|
||||||
| STDOUT
|
| STDOUT
|
||||||
| STORAGE
|
| STORAGE
|
||||||
|
| STRIP
|
||||||
| SUPERUSER_P
|
| SUPERUSER_P
|
||||||
| SYSID
|
| SYSID
|
||||||
| SYSTEM_P
|
| SYSTEM_P
|
||||||
@ -8729,13 +8884,17 @@ unreserved_keyword:
|
|||||||
| VALID
|
| VALID
|
||||||
| VALIDATOR
|
| VALIDATOR
|
||||||
| VARYING
|
| VARYING
|
||||||
|
| VERSION
|
||||||
| VIEW
|
| VIEW
|
||||||
|
| VALUE
|
||||||
| VOLATILE
|
| VOLATILE
|
||||||
|
| WHITESPACE
|
||||||
| WITH
|
| WITH
|
||||||
| WITHOUT
|
| WITHOUT
|
||||||
| WORK
|
| WORK
|
||||||
| WRITE
|
| WRITE
|
||||||
| YEAR_P
|
| YEAR_P
|
||||||
|
| YES
|
||||||
| ZONE
|
| ZONE
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -8788,6 +8947,14 @@ col_name_keyword:
|
|||||||
| TRIM
|
| TRIM
|
||||||
| VALUES
|
| VALUES
|
||||||
| VARCHAR
|
| VARCHAR
|
||||||
|
| XMLATTRIBUTES
|
||||||
|
| XMLELEMENT
|
||||||
|
| XMLCONCAT
|
||||||
|
| XMLFOREST
|
||||||
|
| XMLPARSE
|
||||||
|
| XMLPI
|
||||||
|
| XMLROOT
|
||||||
|
| XMLSERIALIZE
|
||||||
;
|
;
|
||||||
|
|
||||||
/* Function identifier --- keywords that can be function names.
|
/* Function identifier --- keywords that can be function names.
|
||||||
@ -9322,6 +9489,17 @@ doNegateFloat(Value *v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Node *
|
||||||
|
makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
||||||
|
{
|
||||||
|
XmlExpr *x = makeNode(XmlExpr);
|
||||||
|
x->op = op;
|
||||||
|
x->name = name;
|
||||||
|
x->named_args = named_args;
|
||||||
|
x->args = args;
|
||||||
|
return (Node *) x;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must undefine base_yylex before including scan.c, since we want it
|
* Must undefine base_yylex before including scan.c, since we want it
|
||||||
* to create the function base_yylex not filtered_base_yylex.
|
* to create the function base_yylex not filtered_base_yylex.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.177 2006/10/07 21:51:02 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.178 2006/12/21 16:05:14 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -89,6 +89,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"connection", CONNECTION},
|
{"connection", CONNECTION},
|
||||||
{"constraint", CONSTRAINT},
|
{"constraint", CONSTRAINT},
|
||||||
{"constraints", CONSTRAINTS},
|
{"constraints", CONSTRAINTS},
|
||||||
|
{"content", CONTENT},
|
||||||
{"conversion", CONVERSION_P},
|
{"conversion", CONVERSION_P},
|
||||||
{"convert", CONVERT},
|
{"convert", CONVERT},
|
||||||
{"copy", COPY},
|
{"copy", COPY},
|
||||||
@ -123,6 +124,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"disable", DISABLE_P},
|
{"disable", DISABLE_P},
|
||||||
{"distinct", DISTINCT},
|
{"distinct", DISTINCT},
|
||||||
{"do", DO},
|
{"do", DO},
|
||||||
|
{"document", DOCUMENT},
|
||||||
{"domain", DOMAIN_P},
|
{"domain", DOMAIN_P},
|
||||||
{"double", DOUBLE_P},
|
{"double", DOUBLE_P},
|
||||||
{"drop", DROP},
|
{"drop", DROP},
|
||||||
@ -218,6 +220,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"mode", MODE},
|
{"mode", MODE},
|
||||||
{"month", MONTH_P},
|
{"month", MONTH_P},
|
||||||
{"move", MOVE},
|
{"move", MOVE},
|
||||||
|
{"name", NAME},
|
||||||
{"names", NAMES},
|
{"names", NAMES},
|
||||||
{"national", NATIONAL},
|
{"national", NATIONAL},
|
||||||
{"natural", NATURAL},
|
{"natural", NATURAL},
|
||||||
@ -314,6 +317,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"smallint", SMALLINT},
|
{"smallint", SMALLINT},
|
||||||
{"some", SOME},
|
{"some", SOME},
|
||||||
{"stable", STABLE},
|
{"stable", STABLE},
|
||||||
|
{"standalone", STANDALONE},
|
||||||
{"start", START},
|
{"start", START},
|
||||||
{"statement", STATEMENT},
|
{"statement", STATEMENT},
|
||||||
{"statistics", STATISTICS},
|
{"statistics", STATISTICS},
|
||||||
@ -321,6 +325,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"stdout", STDOUT},
|
{"stdout", STDOUT},
|
||||||
{"storage", STORAGE},
|
{"storage", STORAGE},
|
||||||
{"strict", STRICT_P},
|
{"strict", STRICT_P},
|
||||||
|
{"strip", STRIP},
|
||||||
{"substring", SUBSTRING},
|
{"substring", SUBSTRING},
|
||||||
{"superuser", SUPERUSER_P},
|
{"superuser", SUPERUSER_P},
|
||||||
{"symmetric", SYMMETRIC},
|
{"symmetric", SYMMETRIC},
|
||||||
@ -357,19 +362,31 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"vacuum", VACUUM},
|
{"vacuum", VACUUM},
|
||||||
{"valid", VALID},
|
{"valid", VALID},
|
||||||
{"validator", VALIDATOR},
|
{"validator", VALIDATOR},
|
||||||
|
{"value", VALUE},
|
||||||
{"values", VALUES},
|
{"values", VALUES},
|
||||||
{"varchar", VARCHAR},
|
{"varchar", VARCHAR},
|
||||||
{"varying", VARYING},
|
{"varying", VARYING},
|
||||||
{"verbose", VERBOSE},
|
{"verbose", VERBOSE},
|
||||||
|
{"version", VERSION},
|
||||||
{"view", VIEW},
|
{"view", VIEW},
|
||||||
{"volatile", VOLATILE},
|
{"volatile", VOLATILE},
|
||||||
{"when", WHEN},
|
{"when", WHEN},
|
||||||
{"where", WHERE},
|
{"where", WHERE},
|
||||||
|
{"whitespace", WHITESPACE},
|
||||||
{"with", WITH},
|
{"with", WITH},
|
||||||
{"without", WITHOUT},
|
{"without", WITHOUT},
|
||||||
{"work", WORK},
|
{"work", WORK},
|
||||||
{"write", WRITE},
|
{"write", WRITE},
|
||||||
|
{"xmlattributes", XMLATTRIBUTES},
|
||||||
|
{"xmlconcat", XMLCONCAT},
|
||||||
|
{"xmlelement", XMLELEMENT},
|
||||||
|
{"xmlforest", XMLFOREST},
|
||||||
|
{"xmlparse", XMLPARSE},
|
||||||
|
{"xmlpi", XMLPI},
|
||||||
|
{"xmlroot", XMLROOT},
|
||||||
|
{"xmlserialize", XMLSERIALIZE},
|
||||||
{"year", YEAR_P},
|
{"year", YEAR_P},
|
||||||
|
{"yes", YES},
|
||||||
{"zone", ZONE},
|
{"zone", ZONE},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.147 2006/12/10 22:13:26 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.148 2006/12/21 16:05:14 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -919,6 +919,46 @@ coerce_to_bigint(ParseState *pstate, Node *node,
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* coerce_to_xml()
|
||||||
|
* Coerce an argument of a construct that requires xml input.
|
||||||
|
* Also check that input is not a set.
|
||||||
|
*
|
||||||
|
* Returns the possibly-transformed node tree.
|
||||||
|
*
|
||||||
|
* As with coerce_type, pstate may be NULL if no special unknown-Param
|
||||||
|
* processing is wanted.
|
||||||
|
*/
|
||||||
|
Node *
|
||||||
|
coerce_to_xml(ParseState *pstate, Node *node,
|
||||||
|
const char *constructName)
|
||||||
|
{
|
||||||
|
Oid inputTypeId = exprType(node);
|
||||||
|
|
||||||
|
if (inputTypeId != XMLOID)
|
||||||
|
{
|
||||||
|
node = coerce_to_target_type(pstate, node, inputTypeId,
|
||||||
|
XMLOID, -1,
|
||||||
|
COERCION_ASSIGNMENT,
|
||||||
|
COERCE_IMPLICIT_CAST);
|
||||||
|
if (node == NULL)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||||
|
/* translator: first %s is name of a SQL construct, eg LIMIT */
|
||||||
|
errmsg("argument of %s must be type xml, not type %s",
|
||||||
|
constructName, format_type_be(inputTypeId))));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expression_returns_set(node))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||||
|
/* translator: %s is name of a SQL construct, eg LIMIT */
|
||||||
|
errmsg("argument of %s must not return a set",
|
||||||
|
constructName)));
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* select_common_type()
|
/* select_common_type()
|
||||||
* Determine the common supertype of a list of input expression types.
|
* Determine the common supertype of a list of input expression types.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.199 2006/12/10 22:13:26 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.200 2006/12/21 16:05:14 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -33,6 +33,7 @@
|
|||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/xml.h"
|
||||||
|
|
||||||
|
|
||||||
bool Transform_null_equals = false;
|
bool Transform_null_equals = false;
|
||||||
@ -55,6 +56,7 @@ static Node *transformArrayExpr(ParseState *pstate, ArrayExpr *a);
|
|||||||
static Node *transformRowExpr(ParseState *pstate, RowExpr *r);
|
static Node *transformRowExpr(ParseState *pstate, RowExpr *r);
|
||||||
static Node *transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c);
|
static Node *transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c);
|
||||||
static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m);
|
static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m);
|
||||||
|
static Node *transformXmlExpr(ParseState *pstate, XmlExpr *x);
|
||||||
static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
|
static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
|
||||||
static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
|
static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
|
||||||
static Node *transformWholeRowRef(ParseState *pstate, char *schemaname,
|
static Node *transformWholeRowRef(ParseState *pstate, char *schemaname,
|
||||||
@ -232,6 +234,10 @@ transformExpr(ParseState *pstate, Node *expr)
|
|||||||
result = transformBooleanTest(pstate, (BooleanTest *) expr);
|
result = transformBooleanTest(pstate, (BooleanTest *) expr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_XmlExpr:
|
||||||
|
result = transformXmlExpr(pstate, (XmlExpr *) expr);
|
||||||
|
break;
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
* Quietly accept node types that may be presented when we are
|
* Quietly accept node types that may be presented when we are
|
||||||
* called on an already-transformed tree.
|
* called on an already-transformed tree.
|
||||||
@ -1409,6 +1415,56 @@ transformBooleanTest(ParseState *pstate, BooleanTest *b)
|
|||||||
return (Node *) b;
|
return (Node *) b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Node *
|
||||||
|
transformXmlExpr(ParseState *pstate, XmlExpr *x)
|
||||||
|
{
|
||||||
|
ListCell *lc;
|
||||||
|
XmlExpr *newx = makeNode(XmlExpr);
|
||||||
|
|
||||||
|
newx->op = x->op;
|
||||||
|
if (x->name)
|
||||||
|
newx->name = map_sql_identifier_to_xml_name(x->name, false);
|
||||||
|
else
|
||||||
|
newx->name = NULL;
|
||||||
|
|
||||||
|
foreach(lc, x->named_args)
|
||||||
|
{
|
||||||
|
ResTarget *r = (ResTarget *) lfirst(lc);
|
||||||
|
Node *expr = transformExpr(pstate, r->val);
|
||||||
|
char *argname = NULL;
|
||||||
|
|
||||||
|
if (r->name)
|
||||||
|
argname = map_sql_identifier_to_xml_name(r->name, false);
|
||||||
|
else if (IsA(r->val, ColumnRef))
|
||||||
|
argname = map_sql_identifier_to_xml_name(FigureColname(r->val), true);
|
||||||
|
else
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
x->op == IS_XMLELEMENT
|
||||||
|
? errmsg("unnamed attribute value must be a column reference")
|
||||||
|
: errmsg("unnamed element value must be a column reference")));
|
||||||
|
|
||||||
|
newx->named_args = lappend(newx->named_args,
|
||||||
|
makeTargetEntry((Expr *) expr, 0, argname, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(lc, x->args)
|
||||||
|
{
|
||||||
|
Node *e = (Node *) lfirst(lc);
|
||||||
|
Node *newe;
|
||||||
|
|
||||||
|
newe = coerce_to_xml(pstate, transformExpr(pstate, e),
|
||||||
|
(x->op == IS_XMLCONCAT
|
||||||
|
? "XMLCONCAT"
|
||||||
|
: (x->op == IS_XMLELEMENT
|
||||||
|
? "XMLELEMENT"
|
||||||
|
: "XMLFOREST")));
|
||||||
|
newx->args = lappend(newx->args, newe);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Node *) newx;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct a whole-row reference to represent the notation "relation.*".
|
* Construct a whole-row reference to represent the notation "relation.*".
|
||||||
*
|
*
|
||||||
@ -1668,6 +1724,9 @@ exprType(Node *expr)
|
|||||||
case T_BooleanTest:
|
case T_BooleanTest:
|
||||||
type = BOOLOID;
|
type = BOOLOID;
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
type = XMLOID;
|
||||||
|
break;
|
||||||
case T_CoerceToDomain:
|
case T_CoerceToDomain:
|
||||||
type = ((CoerceToDomain *) expr)->resulttype;
|
type = ((CoerceToDomain *) expr)->resulttype;
|
||||||
break;
|
break;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.149 2006/10/04 00:29:56 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.150 2006/12/21 16:05:14 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1315,6 +1315,21 @@ FigureColnameInternal(Node *node, char **name)
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
/* make SQL/XML functions act like a regular function */
|
||||||
|
switch (((XmlExpr*) node)->op)
|
||||||
|
{
|
||||||
|
case IS_XMLCONCAT:
|
||||||
|
*name = "xmlconcat";
|
||||||
|
return 2;
|
||||||
|
case IS_XMLELEMENT:
|
||||||
|
*name = "xmlelement";
|
||||||
|
return 2;
|
||||||
|
case IS_XMLFOREST:
|
||||||
|
*name = "xmlforest";
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for utils/adt
|
# Makefile for utils/adt
|
||||||
#
|
#
|
||||||
# $PostgreSQL: pgsql/src/backend/utils/adt/Makefile,v 1.60 2006/04/05 22:11:55 tgl Exp $
|
# $PostgreSQL: pgsql/src/backend/utils/adt/Makefile,v 1.61 2006/12/21 16:05:15 petere Exp $
|
||||||
#
|
#
|
||||||
|
|
||||||
subdir = src/backend/utils/adt
|
subdir = src/backend/utils/adt
|
||||||
@ -25,7 +25,7 @@ OBJS = acl.o arrayfuncs.o array_userfuncs.o arrayutils.o bool.o \
|
|||||||
tid.o timestamp.o varbit.o varchar.o varlena.o version.o xid.o \
|
tid.o timestamp.o varbit.o varchar.o varlena.o version.o xid.o \
|
||||||
network.o mac.o inet_net_ntop.o inet_net_pton.o \
|
network.o mac.o inet_net_ntop.o inet_net_pton.o \
|
||||||
ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \
|
ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \
|
||||||
ascii.o quote.o pgstatfuncs.o encode.o dbsize.o genfile.o
|
ascii.o quote.o pgstatfuncs.o encode.o dbsize.o genfile.o xml.o
|
||||||
|
|
||||||
like.o: like.c like_match.c
|
like.o: like.c like_match.c
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* ruleutils.c - Functions to convert stored expressions/querytrees
|
* ruleutils.c - Functions to convert stored expressions/querytrees
|
||||||
* back to source text
|
* back to source text
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.235 2006/11/10 22:59:29 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.236 2006/12/21 16:05:15 petere Exp $
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -2988,6 +2988,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
|||||||
case T_CoalesceExpr:
|
case T_CoalesceExpr:
|
||||||
case T_MinMaxExpr:
|
case T_MinMaxExpr:
|
||||||
case T_NullIfExpr:
|
case T_NullIfExpr:
|
||||||
|
case T_XmlExpr:
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
case T_FuncExpr:
|
case T_FuncExpr:
|
||||||
/* function-like: name(..) or name[..] */
|
/* function-like: name(..) or name[..] */
|
||||||
@ -3096,6 +3097,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
|||||||
case T_CoalesceExpr: /* own parentheses */
|
case T_CoalesceExpr: /* own parentheses */
|
||||||
case T_MinMaxExpr: /* own parentheses */
|
case T_MinMaxExpr: /* own parentheses */
|
||||||
case T_NullIfExpr: /* other separators */
|
case T_NullIfExpr: /* other separators */
|
||||||
|
case T_XmlExpr: /* own parentheses */
|
||||||
case T_Aggref: /* own parentheses */
|
case T_Aggref: /* own parentheses */
|
||||||
case T_CaseExpr: /* other separators */
|
case T_CaseExpr: /* other separators */
|
||||||
return true;
|
return true;
|
||||||
@ -3144,6 +3146,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
|||||||
case T_CoalesceExpr: /* own parentheses */
|
case T_CoalesceExpr: /* own parentheses */
|
||||||
case T_MinMaxExpr: /* own parentheses */
|
case T_MinMaxExpr: /* own parentheses */
|
||||||
case T_NullIfExpr: /* other separators */
|
case T_NullIfExpr: /* other separators */
|
||||||
|
case T_XmlExpr: /* own parentheses */
|
||||||
case T_Aggref: /* own parentheses */
|
case T_Aggref: /* own parentheses */
|
||||||
case T_CaseExpr: /* other separators */
|
case T_CaseExpr: /* other separators */
|
||||||
return true;
|
return true;
|
||||||
@ -3845,6 +3848,28 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_XmlExpr:
|
||||||
|
{
|
||||||
|
XmlExpr *xexpr = (XmlExpr *) node;
|
||||||
|
|
||||||
|
switch (xexpr->op)
|
||||||
|
{
|
||||||
|
case IS_XMLCONCAT:
|
||||||
|
appendStringInfo(buf, "XMLCONCAT(");
|
||||||
|
break;
|
||||||
|
case IS_XMLELEMENT:
|
||||||
|
appendStringInfo(buf, "XMLELEMENT(");
|
||||||
|
break;
|
||||||
|
case IS_XMLFOREST:
|
||||||
|
appendStringInfo(buf, "XMLFOREST(");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
get_rule_expr((Node *) xexpr->named_args, context, true);
|
||||||
|
get_rule_expr((Node *) xexpr->args, context, true);
|
||||||
|
appendStringInfoChar(buf, ')');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case T_CoerceToDomain:
|
case T_CoerceToDomain:
|
||||||
{
|
{
|
||||||
CoerceToDomain *ctest = (CoerceToDomain *) node;
|
CoerceToDomain *ctest = (CoerceToDomain *) node;
|
||||||
|
942
src/backend/utils/adt/xml.c
Normal file
942
src/backend/utils/adt/xml.c
Normal file
@ -0,0 +1,942 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* xml.c
|
||||||
|
* XML data type support.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.1 2006/12/21 16:05:15 petere Exp $
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generally, XML type support is only available when libxml use was
|
||||||
|
* configured during the build. But even if that is not done, the
|
||||||
|
* type and all the functions are available, but most of them will
|
||||||
|
* fail. For one thing, this avoids having to manage variant catalog
|
||||||
|
* installations. But it also has nice effects such as that you can
|
||||||
|
* dump a database containing XML type data even if the server is not
|
||||||
|
* linked with libxml.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
#include <libxml/chvalid.h>
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
#include <libxml/uri.h>
|
||||||
|
#include <libxml/xmlerror.h>
|
||||||
|
#endif /* USE_LIBXML */
|
||||||
|
|
||||||
|
#include "fmgr.h"
|
||||||
|
#include "mb/pg_wchar.h"
|
||||||
|
#include "nodes/execnodes.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/xml.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A couple of useful macros (similar to ones from libxml/parse.c)
|
||||||
|
*/
|
||||||
|
#define CMP4( s, c1, c2, c3, c4 ) \
|
||||||
|
( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
|
||||||
|
((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
|
||||||
|
#define CMP5( s, c1, c2, c3, c4, c5 ) \
|
||||||
|
( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
|
||||||
|
|
||||||
|
#define PG_XML_DEFAULT_URI "dummy.xml"
|
||||||
|
#define XML_ERRBUF_SIZE 200
|
||||||
|
|
||||||
|
|
||||||
|
static void xml_init(void);
|
||||||
|
static void *xml_palloc(size_t size);
|
||||||
|
static void *xml_repalloc(void *ptr, size_t size);
|
||||||
|
static void xml_pfree(void *ptr);
|
||||||
|
static char *xml_pstrdup(const char *string);
|
||||||
|
static void xml_ereport(int level, char *msg, void *ctxt);
|
||||||
|
static void xml_errorHandler(void *ctxt, const char *msg, ...);
|
||||||
|
static void xml_ereport_by_code(int level, char *msg, int errcode);
|
||||||
|
static xmlChar *xml_text2xmlChar(text *in);
|
||||||
|
static xmlDocPtr xml_parse(text *data, int opts, bool is_document);
|
||||||
|
|
||||||
|
|
||||||
|
/* Global variables */
|
||||||
|
/* taken from contrib/xml2 */
|
||||||
|
/* FIXME: DO NOT USE global vars !!! */
|
||||||
|
char *xml_errbuf; /* per line error buffer */
|
||||||
|
char *xml_errmsg = NULL; /* overall error message */
|
||||||
|
|
||||||
|
#endif /* USE_LIBXML */
|
||||||
|
|
||||||
|
|
||||||
|
#define NO_XML_SUPPORT() ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("no XML support in this installation")))
|
||||||
|
|
||||||
|
|
||||||
|
Datum
|
||||||
|
xml_in(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
char *s = PG_GETARG_CSTRING(0);
|
||||||
|
size_t len;
|
||||||
|
xmltype *vardata;
|
||||||
|
|
||||||
|
len = strlen(s);
|
||||||
|
vardata = palloc(len + VARHDRSZ);
|
||||||
|
VARATT_SIZEP(vardata) = len + VARHDRSZ;
|
||||||
|
memcpy(VARDATA(vardata), s, len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the data to check if it is well-formed XML data. Assume
|
||||||
|
* that ERROR occurred if parsing failed. Do we need DTD
|
||||||
|
* validation (if DTD exists)?
|
||||||
|
*/
|
||||||
|
xml_parse(vardata, XML_PARSE_DTDATTR | XML_PARSE_DTDVALID, false);
|
||||||
|
|
||||||
|
PG_RETURN_XML_P(vardata);
|
||||||
|
#else
|
||||||
|
NO_XML_SUPPORT();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Datum
|
||||||
|
xml_out(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
xmltype *s = PG_GETARG_XML_P(0);
|
||||||
|
char *result;
|
||||||
|
int32 len;
|
||||||
|
|
||||||
|
len = VARSIZE(s) - VARHDRSZ;
|
||||||
|
result = palloc(len + 1);
|
||||||
|
memcpy(result, VARDATA(s), len);
|
||||||
|
result[len] = '\0';
|
||||||
|
|
||||||
|
PG_RETURN_CSTRING(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
static void
|
||||||
|
appendStringInfoText(StringInfo str, const text *t)
|
||||||
|
{
|
||||||
|
appendBinaryStringInfo(str, VARDATA(t), VARSIZE(t) - VARHDRSZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static xmltype *
|
||||||
|
stringinfo_to_xmltype(StringInfo buf)
|
||||||
|
{
|
||||||
|
int32 len;
|
||||||
|
xmltype *result;
|
||||||
|
|
||||||
|
len = buf->len + VARHDRSZ;
|
||||||
|
result = palloc(len);
|
||||||
|
VARATT_SIZEP(result) = len;
|
||||||
|
memcpy(VARDATA(result), buf->data, buf->len);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
Datum
|
||||||
|
xmlcomment(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
text *arg = PG_GETARG_TEXT_P(0);
|
||||||
|
int len = VARATT_SIZEP(arg) - VARHDRSZ;
|
||||||
|
StringInfoData buf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* check for "--" in string or "-" at the end */
|
||||||
|
for (i = 1; i < len; i++)
|
||||||
|
if ((VARDATA(arg)[i] == '-' && VARDATA(arg)[i - 1] == '-')
|
||||||
|
|| (VARDATA(arg)[i] == '-' && i == len - 1))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_XML_COMMENT),
|
||||||
|
errmsg("invalid XML comment")));
|
||||||
|
|
||||||
|
initStringInfo(&buf);
|
||||||
|
appendStringInfo(&buf, "<!--");
|
||||||
|
appendStringInfoText(&buf, arg);
|
||||||
|
appendStringInfo(&buf, "-->");
|
||||||
|
|
||||||
|
PG_RETURN_XML_P(stringinfo_to_xmltype(&buf));
|
||||||
|
#else
|
||||||
|
NO_XML_SUPPORT();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Datum
|
||||||
|
xmlparse(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
text *data;
|
||||||
|
bool is_document;
|
||||||
|
bool preserve_whitespace;
|
||||||
|
|
||||||
|
data = PG_GETARG_TEXT_P(0);
|
||||||
|
|
||||||
|
if (PG_NARGS() >= 2)
|
||||||
|
is_document = PG_GETARG_BOOL(1);
|
||||||
|
else
|
||||||
|
is_document = false;
|
||||||
|
|
||||||
|
if (PG_NARGS() >= 3)
|
||||||
|
preserve_whitespace = PG_GETARG_BOOL(2);
|
||||||
|
else
|
||||||
|
/*
|
||||||
|
* Since the XMLPARSE grammar makes STRIP WHITESPACE the
|
||||||
|
* default, this argument should really default to false. But
|
||||||
|
* until we have actually implemented whitespace stripping,
|
||||||
|
* this would be annoying.
|
||||||
|
*/
|
||||||
|
preserve_whitespace = true;
|
||||||
|
|
||||||
|
if (!preserve_whitespace)
|
||||||
|
ereport(WARNING,
|
||||||
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("XMLPARSE with STRIP WHITESPACE is not implemented")));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note, that here we try to apply DTD defaults
|
||||||
|
* (XML_PARSE_DTDATTR) according to SQL/XML:10.16.7.d: 'Default
|
||||||
|
* valies defined by internal DTD are applied'. As for external
|
||||||
|
* DTDs, we try to support them too, (see SQL/XML:10.16.7.e)
|
||||||
|
*/
|
||||||
|
xml_parse(data, XML_PARSE_DTDATTR, is_document); /* assume that ERROR occurred if parsing failed */
|
||||||
|
|
||||||
|
PG_RETURN_XML_P(data);
|
||||||
|
#else
|
||||||
|
NO_XML_SUPPORT();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Datum
|
||||||
|
xmlpi(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
char *target = NameStr(*PG_GETARG_NAME(0));
|
||||||
|
StringInfoData buf;
|
||||||
|
|
||||||
|
if (strlen(target) >= 3
|
||||||
|
&& (target[0] == 'x' || target[0] == 'X')
|
||||||
|
&& (target[1] == 'm' || target[1] == 'M')
|
||||||
|
&& (target[2] == 'l' || target[2] == 'L'))
|
||||||
|
{
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
errmsg("invalid XML processing instruction"),
|
||||||
|
errdetail("XML processing instruction target name cannot start with \"xml\".")));
|
||||||
|
}
|
||||||
|
|
||||||
|
initStringInfo(&buf);
|
||||||
|
|
||||||
|
appendStringInfo(&buf, "<?");
|
||||||
|
appendStringInfoString(&buf, map_sql_identifier_to_xml_name(target, false));
|
||||||
|
if (PG_NARGS() > 1)
|
||||||
|
{
|
||||||
|
text *arg = PG_GETARG_TEXT_P(1);
|
||||||
|
char *string;
|
||||||
|
|
||||||
|
string = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(arg)));
|
||||||
|
if (strstr(string, "?>"))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
|
||||||
|
errmsg("invalid XML processing instruction"),
|
||||||
|
errdetail("XML processing instruction cannot contain \"?>\".")));
|
||||||
|
|
||||||
|
appendStringInfoString(&buf, " ");
|
||||||
|
appendStringInfoString(&buf, string);
|
||||||
|
}
|
||||||
|
appendStringInfoString(&buf, "?>");
|
||||||
|
|
||||||
|
PG_RETURN_XML_P(stringinfo_to_xmltype(&buf));
|
||||||
|
#else
|
||||||
|
NO_XML_SUPPORT();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Datum
|
||||||
|
xmlroot(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
xmltype *data;
|
||||||
|
text *version;
|
||||||
|
int standalone;
|
||||||
|
StringInfoData buf;
|
||||||
|
|
||||||
|
if (PG_ARGISNULL(0))
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
else
|
||||||
|
data = PG_GETARG_XML_P(0);
|
||||||
|
|
||||||
|
if (PG_ARGISNULL(1))
|
||||||
|
version = NULL;
|
||||||
|
else
|
||||||
|
version = PG_GETARG_TEXT_P(1);
|
||||||
|
|
||||||
|
if (PG_ARGISNULL(2))
|
||||||
|
standalone = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool tmp = PG_GETARG_BOOL(2);
|
||||||
|
standalone = (tmp ? 1 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: This is probably supposed to be cleverer if there
|
||||||
|
* already is an XML preamble.
|
||||||
|
*/
|
||||||
|
initStringInfo(&buf);
|
||||||
|
|
||||||
|
appendStringInfo(&buf,"<?xml");
|
||||||
|
if (version) {
|
||||||
|
appendStringInfo(&buf, " version=\"");
|
||||||
|
appendStringInfoText(&buf, version);
|
||||||
|
appendStringInfo(&buf, "\"");
|
||||||
|
}
|
||||||
|
if (standalone)
|
||||||
|
appendStringInfo(&buf, " standalone=\"%s\"", (standalone == 1 ? "yes" : "no"));
|
||||||
|
appendStringInfo(&buf, "?>");
|
||||||
|
appendStringInfoText(&buf, (text *) data);
|
||||||
|
|
||||||
|
PG_RETURN_XML_P(stringinfo_to_xmltype(&buf));
|
||||||
|
#else
|
||||||
|
NO_XML_SUPPORT();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate document (given as string) against DTD (given as external link)
|
||||||
|
* TODO !!! use text instead of cstring for second arg
|
||||||
|
* TODO allow passing DTD as a string value (not only as an URI)
|
||||||
|
* TODO redesign (see comment with '!!!' below)
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
xmlvalidate(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
text *data = PG_GETARG_TEXT_P(0);
|
||||||
|
text *dtdOrUri = PG_GETARG_TEXT_P(1);
|
||||||
|
bool result = FALSE;
|
||||||
|
xmlParserCtxtPtr ctxt; /* the parser context */
|
||||||
|
xmlDocPtr doc; /* the resulting document tree */
|
||||||
|
xmlDtdPtr dtd;
|
||||||
|
|
||||||
|
xml_init();
|
||||||
|
|
||||||
|
ctxt = xmlNewParserCtxt();
|
||||||
|
if (ctxt == NULL)
|
||||||
|
xml_ereport(ERROR, "could not allocate parser context", ctxt);
|
||||||
|
doc = xmlCtxtReadMemory(ctxt, (char *) VARDATA(data),
|
||||||
|
VARSIZE(data) - VARHDRSZ, PG_XML_DEFAULT_URI, NULL, 0);
|
||||||
|
if (doc == NULL)
|
||||||
|
xml_ereport(ERROR, "could not parse XML data", ctxt);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
uri = xmlCreateURI();
|
||||||
|
ereport(NOTICE, (errcode(0),errmsg(" dtd - %s", dtdOrUri)));
|
||||||
|
dtd = palloc(sizeof(xmlDtdPtr));
|
||||||
|
uri = xmlParseURI(dtdOrUri);
|
||||||
|
if (uri == NULL)
|
||||||
|
xml_ereport(ERROR, "not implemented yet... (TODO)", ctxt);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
dtd = xmlParseDTD(NULL, xml_text2xmlChar(dtdOrUri));
|
||||||
|
|
||||||
|
if (dtd == NULL)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
#endif
|
||||||
|
xml_ereport(ERROR, "could not load DTD", ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xmlValidateDtd(xmlNewValidCtxt(), doc, dtd) == 1)
|
||||||
|
result = TRUE;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
xmlFreeURI(uri);
|
||||||
|
xmlFreeDtd(dtd);
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
xmlCleanupParser();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
xml_ereport(NOTICE, "validation against DTD failed", ctxt);
|
||||||
|
|
||||||
|
PG_RETURN_BOOL(result);
|
||||||
|
#else /* not USE_LIBXML */
|
||||||
|
NO_XML_SUPPORT();
|
||||||
|
return 0;
|
||||||
|
#endif /* not USE_LIBXML */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Container for some init stuff (not good design!)
|
||||||
|
* TODO xmlChar is utf8-char, make proper tuning (initdb with enc!=utf8 and check)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
xml_init(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Currently, we have no pure UTF-8 support for internals -- check
|
||||||
|
* if we can work.
|
||||||
|
*/
|
||||||
|
if (sizeof (char) != sizeof (xmlChar))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errmsg("cannot initialize XML library"),
|
||||||
|
errdetail("libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u.",
|
||||||
|
sizeof(char), sizeof(xmlChar))));
|
||||||
|
|
||||||
|
xmlMemSetup(xml_pfree, xml_palloc, xml_repalloc, xml_pstrdup);
|
||||||
|
xmlInitParser();
|
||||||
|
LIBXML_TEST_VERSION;
|
||||||
|
/* do not flood PG's logfile with libxml error messages - reset error handler*/
|
||||||
|
xmlSetGenericErrorFunc(NULL, xml_errorHandler);
|
||||||
|
xml_errmsg = NULL;
|
||||||
|
xml_errbuf = palloc(XML_ERRBUF_SIZE);
|
||||||
|
memset(xml_errbuf, 0, XML_ERRBUF_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a C string to XML internal representation
|
||||||
|
* (same things as for TEXT, but with checking the data for well-formedness
|
||||||
|
* and, moreover, validation against DTD, if needed).
|
||||||
|
* NOTICE: We use TEXT type as internal storage type. In the future,
|
||||||
|
* we plan to create own storage type (maybe several types/strategies)
|
||||||
|
* TODO predefined DTDs / XSDs and validation
|
||||||
|
* TODO validation against XML Schema
|
||||||
|
* TODO maybe, libxml2's xmlreader is better? (do not construct DOM, yet do not use SAX - see xml_reader.c)
|
||||||
|
* TODO what about internal URI for docs? (see PG_XML_DEFAULT_URI below)
|
||||||
|
*/
|
||||||
|
static xmlDocPtr
|
||||||
|
xml_parse(text *data, int opts, bool is_document)
|
||||||
|
{
|
||||||
|
bool validationFailed = FALSE;
|
||||||
|
xmlParserCtxtPtr ctxt; /* the parser context */
|
||||||
|
xmlDocPtr doc; /* the resulting document tree */
|
||||||
|
int res_code;
|
||||||
|
int32 len;
|
||||||
|
xmlChar *string;
|
||||||
|
#ifdef XML_DEBUG_DTD_CONST
|
||||||
|
xmlDtdPtr dtd; /* pointer to DTD */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
xml_init();
|
||||||
|
|
||||||
|
len = VARSIZE(data) - VARHDRSZ; /* will be useful later */
|
||||||
|
string = xml_text2xmlChar(data);
|
||||||
|
|
||||||
|
ctxt = xmlNewParserCtxt();
|
||||||
|
if (ctxt == NULL)
|
||||||
|
xml_ereport(ERROR, "could not allocate parser context", ctxt);
|
||||||
|
|
||||||
|
/* first, we try to parse the string as it is XML doc, then, as XML chunk */
|
||||||
|
ereport(DEBUG3, (errmsg("string to parse: %s", string)));
|
||||||
|
if (len > 4 && CMP5(string, '<', '?', 'x', 'm', 'l'))
|
||||||
|
{
|
||||||
|
/* consider it as DOCUMENT */
|
||||||
|
doc = xmlCtxtReadMemory(ctxt, string, len, PG_XML_DEFAULT_URI, NULL, opts);
|
||||||
|
if (doc == NULL)
|
||||||
|
{
|
||||||
|
xml_ereport(ERROR, "could not parse XML data", ctxt);
|
||||||
|
#if 0
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
xmlCleanupParser();
|
||||||
|
ereport(ERROR, (errmsg("could not parse XML data")));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* attempt to parse the string as if it is an XML fragment */
|
||||||
|
ereport(DEBUG3, (errmsg("the string is not an XML doc, trying to parse as a CHUNK")));
|
||||||
|
doc = xmlNewDoc(NULL);
|
||||||
|
/* TODO resolve: xmlParseBalancedChunkMemory assumes that string is UTF8 encoded! */
|
||||||
|
res_code = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0, string, NULL);
|
||||||
|
if (res_code != 0)
|
||||||
|
{
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
xmlCleanupParser();
|
||||||
|
xml_ereport_by_code(ERROR, "could not parse XML data", res_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef XML_DEBUG_DTD_CONST
|
||||||
|
dtd = xmlParseDTD(NULL, (xmlChar *) XML_DEBUG_DTD_CONST);
|
||||||
|
xml_ereport(DEBUG3, "solid path to DTD was defined for debugging purposes", ctxt);
|
||||||
|
if (dtd == NULL)
|
||||||
|
{
|
||||||
|
xml_ereport(ERROR, "could not parse DTD data", ctxt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#else
|
||||||
|
/* if dtd for our xml data is detected... */
|
||||||
|
if ((doc->intSubset != NULL) || (doc->extSubset != NULL))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* assume that inline DTD exists - validation should be performed */
|
||||||
|
#ifdef XML_DEBUG_DTD_CONST
|
||||||
|
if (xmlValidateDtd(xmlNewValidCtxt(), doc, dtd) != 1)
|
||||||
|
#else
|
||||||
|
if (ctxt->valid == 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* DTD exists, but validator reported 'validation failed' */
|
||||||
|
validationFailed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validationFailed)
|
||||||
|
xml_ereport(WARNING, "validation against DTD failed", ctxt);
|
||||||
|
|
||||||
|
/* TODO encoding issues
|
||||||
|
* (thoughts:
|
||||||
|
* CASE:
|
||||||
|
* - XML data has explicit encoding attribute in its prolog
|
||||||
|
* - if not, assume that enc. of XML data is the same as client's one
|
||||||
|
*
|
||||||
|
* The common rule is to accept the XML data only if its encoding
|
||||||
|
* is the same as encoding of the storage (server's). The other possible
|
||||||
|
* option is to accept all the docs, but DO TRANSFORMATION and, if needed,
|
||||||
|
* change the prolog.
|
||||||
|
*
|
||||||
|
* I think I'd stick the first way (for the 1st version),
|
||||||
|
* it's much simplier (less errors...)
|
||||||
|
* ) */
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
xmlCleanupParser();
|
||||||
|
|
||||||
|
ereport(DEBUG3, (errmsg("XML data successfully parsed, encoding: %s",
|
||||||
|
(char *) doc->encoding)));
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xmlChar<->text convertions
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrappers for memory management functions
|
||||||
|
*/
|
||||||
|
static void *
|
||||||
|
xml_palloc(size_t size)
|
||||||
|
{
|
||||||
|
return palloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *
|
||||||
|
xml_repalloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
return repalloc(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
xml_pfree(void *ptr)
|
||||||
|
{
|
||||||
|
pfree(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
xml_pstrdup(const char *string)
|
||||||
|
{
|
||||||
|
return pstrdup(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapper for "ereport" function.
|
||||||
|
* Adds detail - libxml's native error message, if any.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
xml_ereport(int level, char *msg, void *ctxt)
|
||||||
|
{
|
||||||
|
char *xmlErrDetail;
|
||||||
|
int xmlErrLen, i;
|
||||||
|
xmlErrorPtr libxmlErr = NULL;
|
||||||
|
|
||||||
|
if (xml_errmsg != NULL)
|
||||||
|
{
|
||||||
|
ereport(DEBUG1, (errmsg("%s", xml_errmsg)));
|
||||||
|
pfree(xml_errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxt != NULL)
|
||||||
|
libxmlErr = xmlCtxtGetLastError(ctxt);
|
||||||
|
|
||||||
|
if (libxmlErr == NULL)
|
||||||
|
{
|
||||||
|
if (level == ERROR)
|
||||||
|
{
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
xmlCleanupParser();
|
||||||
|
}
|
||||||
|
ereport(level, (errmsg(msg)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* as usual, libxml error message contains '\n'; get rid of it */
|
||||||
|
xmlErrLen = strlen(libxmlErr->message); /* - 1; */
|
||||||
|
xmlErrDetail = (char *) palloc(xmlErrLen);
|
||||||
|
for (i = 0; i < xmlErrLen; i++)
|
||||||
|
{
|
||||||
|
if (libxmlErr->message[i] == '\n')
|
||||||
|
xmlErrDetail[i] = '.';
|
||||||
|
else
|
||||||
|
xmlErrDetail[i] = libxmlErr->message[i];
|
||||||
|
}
|
||||||
|
if (level == ERROR)
|
||||||
|
{
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
xmlCleanupParser();
|
||||||
|
}
|
||||||
|
ereport(level, (errmsg(msg), errdetail("%s", xmlErrDetail)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error handler for libxml error messages
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
xml_errorHandler(void *ctxt, const char *msg,...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, msg);
|
||||||
|
vsnprintf(xml_errbuf, XML_ERRBUF_SIZE, msg, args);
|
||||||
|
va_end(args);
|
||||||
|
/* Now copy the argument across */
|
||||||
|
if (xml_errmsg == NULL)
|
||||||
|
xml_errmsg = pstrdup(xml_errbuf);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int32 xsize = strlen(xml_errmsg);
|
||||||
|
|
||||||
|
xml_errmsg = repalloc(xml_errmsg, (size_t) (xsize + strlen(xml_errbuf) + 1));
|
||||||
|
strncpy(&xml_errmsg[xsize - 1], xml_errbuf, strlen(xml_errbuf));
|
||||||
|
xml_errmsg[xsize + strlen(xml_errbuf) - 1] = '\0';
|
||||||
|
}
|
||||||
|
memset(xml_errbuf, 0, XML_ERRBUF_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return error message by libxml error code
|
||||||
|
* TODO make them closer to recommendations from Postgres manual
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
xml_ereport_by_code(int level, char *msg, int code)
|
||||||
|
{
|
||||||
|
const char *det;
|
||||||
|
|
||||||
|
if (code < 0)
|
||||||
|
{
|
||||||
|
ereport(level, (errmsg(msg)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (code) {
|
||||||
|
case XML_ERR_INTERNAL_ERROR:
|
||||||
|
det = "libxml internal error";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ENTITY_LOOP:
|
||||||
|
det = "Detected an entity reference loop";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ENTITY_NOT_STARTED:
|
||||||
|
det = "EntityValue: \" or ' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ENTITY_NOT_FINISHED:
|
||||||
|
det = "EntityValue: \" or ' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ATTRIBUTE_NOT_STARTED:
|
||||||
|
det = "AttValue: \" or ' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_LT_IN_ATTRIBUTE:
|
||||||
|
det = "Unescaped '<' not allowed in attributes values";
|
||||||
|
break;
|
||||||
|
case XML_ERR_LITERAL_NOT_STARTED:
|
||||||
|
det = "SystemLiteral \" or ' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_LITERAL_NOT_FINISHED:
|
||||||
|
det = "Unfinished System or Public ID \" or ' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_MISPLACED_CDATA_END:
|
||||||
|
det = "Sequence ']]>' not allowed in content";
|
||||||
|
break;
|
||||||
|
case XML_ERR_URI_REQUIRED:
|
||||||
|
det = "SYSTEM or PUBLIC, the URI is missing";
|
||||||
|
break;
|
||||||
|
case XML_ERR_PUBID_REQUIRED:
|
||||||
|
det = "PUBLIC, the Public Identifier is missing";
|
||||||
|
break;
|
||||||
|
case XML_ERR_HYPHEN_IN_COMMENT:
|
||||||
|
det = "Comment must not contain '--' (double-hyphen)";
|
||||||
|
break;
|
||||||
|
case XML_ERR_PI_NOT_STARTED:
|
||||||
|
det = "xmlParsePI : no target name";
|
||||||
|
break;
|
||||||
|
case XML_ERR_RESERVED_XML_NAME:
|
||||||
|
det = "Invalid PI name";
|
||||||
|
break;
|
||||||
|
case XML_ERR_NOTATION_NOT_STARTED:
|
||||||
|
det = "NOTATION: Name expected here";
|
||||||
|
break;
|
||||||
|
case XML_ERR_NOTATION_NOT_FINISHED:
|
||||||
|
det = "'>' required to close NOTATION declaration";
|
||||||
|
break;
|
||||||
|
case XML_ERR_VALUE_REQUIRED:
|
||||||
|
det = "Entity value required";
|
||||||
|
break;
|
||||||
|
case XML_ERR_URI_FRAGMENT:
|
||||||
|
det = "Fragment not allowed";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ATTLIST_NOT_STARTED:
|
||||||
|
det = "'(' required to start ATTLIST enumeration";
|
||||||
|
break;
|
||||||
|
case XML_ERR_NMTOKEN_REQUIRED:
|
||||||
|
det = "NmToken expected in ATTLIST enumeration";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ATTLIST_NOT_FINISHED:
|
||||||
|
det = "')' required to finish ATTLIST enumeration";
|
||||||
|
break;
|
||||||
|
case XML_ERR_MIXED_NOT_STARTED:
|
||||||
|
det = "MixedContentDecl : '|' or ')*' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_PCDATA_REQUIRED:
|
||||||
|
det = "MixedContentDecl : '#PCDATA' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ELEMCONTENT_NOT_STARTED:
|
||||||
|
det = "ContentDecl : Name or '(' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ELEMCONTENT_NOT_FINISHED:
|
||||||
|
det = "ContentDecl : ',' '|' or ')' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_PEREF_IN_INT_SUBSET:
|
||||||
|
det = "PEReference: forbidden within markup decl in internal subset";
|
||||||
|
break;
|
||||||
|
case XML_ERR_GT_REQUIRED:
|
||||||
|
det = "Expected '>'";
|
||||||
|
break;
|
||||||
|
case XML_ERR_CONDSEC_INVALID:
|
||||||
|
det = "XML conditional section '[' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_EXT_SUBSET_NOT_FINISHED:
|
||||||
|
det = "Content error in the external subset";
|
||||||
|
break;
|
||||||
|
case XML_ERR_CONDSEC_INVALID_KEYWORD:
|
||||||
|
det = "conditional section INCLUDE or IGNORE keyword expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_CONDSEC_NOT_FINISHED:
|
||||||
|
det = "XML conditional section not closed";
|
||||||
|
break;
|
||||||
|
case XML_ERR_XMLDECL_NOT_STARTED:
|
||||||
|
det = "Text declaration '<?xml' required";
|
||||||
|
break;
|
||||||
|
case XML_ERR_XMLDECL_NOT_FINISHED:
|
||||||
|
det = "parsing XML declaration: '?>' expected";
|
||||||
|
break;
|
||||||
|
case XML_ERR_EXT_ENTITY_STANDALONE:
|
||||||
|
det = "external parsed entities cannot be standalone";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ENTITYREF_SEMICOL_MISSING:
|
||||||
|
det = "EntityRef: expecting ';'";
|
||||||
|
break;
|
||||||
|
case XML_ERR_DOCTYPE_NOT_FINISHED:
|
||||||
|
det = "DOCTYPE improperly terminated";
|
||||||
|
break;
|
||||||
|
case XML_ERR_LTSLASH_REQUIRED:
|
||||||
|
det = "EndTag: '</' not found";
|
||||||
|
break;
|
||||||
|
case XML_ERR_EQUAL_REQUIRED:
|
||||||
|
det = "Expected '='";
|
||||||
|
break;
|
||||||
|
case XML_ERR_STRING_NOT_CLOSED:
|
||||||
|
det = "String not closed expecting \" or '";
|
||||||
|
break;
|
||||||
|
case XML_ERR_STRING_NOT_STARTED:
|
||||||
|
det = "String not started expecting ' or \"";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ENCODING_NAME:
|
||||||
|
det = "Invalid XML encoding name";
|
||||||
|
break;
|
||||||
|
case XML_ERR_STANDALONE_VALUE:
|
||||||
|
det = "Standalone accepts only 'yes' or 'no'";
|
||||||
|
break;
|
||||||
|
case XML_ERR_DOCUMENT_EMPTY:
|
||||||
|
det = "Document is empty";
|
||||||
|
break;
|
||||||
|
case XML_ERR_DOCUMENT_END:
|
||||||
|
det = "Extra content at the end of the document";
|
||||||
|
break;
|
||||||
|
case XML_ERR_NOT_WELL_BALANCED:
|
||||||
|
det = "Chunk is not well balanced";
|
||||||
|
break;
|
||||||
|
case XML_ERR_EXTRA_CONTENT:
|
||||||
|
det = "Extra content at the end of well balanced chunk";
|
||||||
|
break;
|
||||||
|
case XML_ERR_VERSION_MISSING:
|
||||||
|
det = "Malformed declaration expecting version";
|
||||||
|
break;
|
||||||
|
/* more err codes... Please, keep the order! */
|
||||||
|
case XML_ERR_ATTRIBUTE_WITHOUT_VALUE: /* 41 */
|
||||||
|
det ="Attribute without value";
|
||||||
|
break;
|
||||||
|
case XML_ERR_ATTRIBUTE_REDEFINED:
|
||||||
|
det ="Attribute defined more than once in the same element";
|
||||||
|
break;
|
||||||
|
case XML_ERR_COMMENT_NOT_FINISHED: /* 45 */
|
||||||
|
det = "Comment is not finished";
|
||||||
|
break;
|
||||||
|
case XML_ERR_NAME_REQUIRED: /* 68 */
|
||||||
|
det = "Element name not found";
|
||||||
|
break;
|
||||||
|
case XML_ERR_TAG_NOT_FINISHED: /* 77 */
|
||||||
|
det = "Closing tag not found";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
det = "Unregistered error (libxml error code: %d)";
|
||||||
|
ereport(DEBUG1, (errmsg("Check out \"libxml/xmlerror.h\" and bring errcode \"%d\" processing to \"xml.c\".", code)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xml_errmsg != NULL)
|
||||||
|
{
|
||||||
|
ereport(DEBUG1, (errmsg("%s", xml_errmsg)));
|
||||||
|
pfree(xml_errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ereport(level, (errmsg(msg), errdetail(det, code)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert one char in the current server encoding to a Unicode
|
||||||
|
* codepoint.
|
||||||
|
*/
|
||||||
|
static pg_wchar
|
||||||
|
sqlchar_to_unicode(unsigned char *s)
|
||||||
|
{
|
||||||
|
int save_enc;
|
||||||
|
pg_wchar ret;
|
||||||
|
char *utf8string = pg_do_encoding_conversion(s, pg_mblen(s), GetDatabaseEncoding(), PG_UTF8);
|
||||||
|
|
||||||
|
save_enc = GetDatabaseEncoding();
|
||||||
|
SetDatabaseEncoding(PG_UTF8);
|
||||||
|
pg_mb2wchar_with_len(utf8string, &ret, pg_mblen(s));
|
||||||
|
SetDatabaseEncoding(save_enc);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_valid_xml_namefirst(pg_wchar c)
|
||||||
|
{
|
||||||
|
/* (Letter | '_' | ':') */
|
||||||
|
return (xmlIsBaseCharQ(c) || xmlIsIdeographicQ(c)
|
||||||
|
|| c == '_' || c == ':');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_valid_xml_namechar(pg_wchar c)
|
||||||
|
{
|
||||||
|
/* Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender */
|
||||||
|
return (xmlIsBaseCharQ(c) || xmlIsIdeographicQ(c)
|
||||||
|
|| xmlIsDigitQ(c)
|
||||||
|
|| c == '.' || c == '-' || c == '_' || c == ':'
|
||||||
|
|| xmlIsCombiningQ(c)
|
||||||
|
|| xmlIsExtenderQ(c));
|
||||||
|
}
|
||||||
|
#endif /* USE_LIBXML */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map SQL identifier to XML name; see SQL/XML:2003 section 9.1.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
map_sql_identifier_to_xml_name(unsigned char *ident, bool fully_escaped)
|
||||||
|
{
|
||||||
|
#ifdef USE_LIBXML
|
||||||
|
StringInfoData buf;
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
initStringInfo(&buf);
|
||||||
|
|
||||||
|
for (p = ident; *p; p += pg_mblen(p))
|
||||||
|
{
|
||||||
|
if (*p == ':' && (p == ident || fully_escaped))
|
||||||
|
appendStringInfo(&buf, "_x003A_");
|
||||||
|
else if (*p == '_' && *(p+1) == 'x')
|
||||||
|
appendStringInfo(&buf, "_x005F_");
|
||||||
|
else if (fully_escaped && p == ident
|
||||||
|
&& ( *p == 'x' || *p == 'X')
|
||||||
|
&& ( *(p+1) == 'm' || *(p+1) == 'M')
|
||||||
|
&& ( *(p+2) == 'l' || *(p+2) == 'L'))
|
||||||
|
{
|
||||||
|
if (*p == 'x')
|
||||||
|
appendStringInfo(&buf, "_x0078_");
|
||||||
|
else
|
||||||
|
appendStringInfo(&buf, "_x0058_");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pg_wchar u = sqlchar_to_unicode(p);
|
||||||
|
|
||||||
|
if (!is_valid_xml_namechar(u)
|
||||||
|
|| (p == ident && !is_valid_xml_namefirst(u)))
|
||||||
|
appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
|
||||||
|
else
|
||||||
|
appendBinaryStringInfo(&buf, p, pg_mblen(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.data;
|
||||||
|
#else /* not USE_LIBXML */
|
||||||
|
NO_XML_SUPPORT();
|
||||||
|
return NULL;
|
||||||
|
#endif /* not USE_LIBXML */
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
* (currently mule internal code (mic) is used)
|
* (currently mule internal code (mic) is used)
|
||||||
* Tatsuo Ishii
|
* Tatsuo Ishii
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.59 2006/10/04 00:30:02 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.60 2006/12/21 16:05:15 petere Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
@ -599,7 +599,7 @@ void
|
|||||||
SetDatabaseEncoding(int encoding)
|
SetDatabaseEncoding(int encoding)
|
||||||
{
|
{
|
||||||
if (!PG_VALID_BE_ENCODING(encoding))
|
if (!PG_VALID_BE_ENCODING(encoding))
|
||||||
elog(ERROR, "invalid database encoding");
|
elog(ERROR, "invalid database encoding: %d", encoding);
|
||||||
|
|
||||||
DatabaseEncoding = &pg_enc2name_tbl[encoding];
|
DatabaseEncoding = &pg_enc2name_tbl[encoding];
|
||||||
Assert(DatabaseEncoding->encoding == encoding);
|
Assert(DatabaseEncoding->encoding == encoding);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2002-2006, PostgreSQL Global Development Group
|
* Copyright (c) 2002-2006, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.26 2006/03/05 15:58:54 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.27 2006/12/21 16:05:15 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -300,6 +300,8 @@ DATA(insert ( 1266 25 939 i ));
|
|||||||
DATA(insert ( 25 1266 938 e ));
|
DATA(insert ( 25 1266 938 e ));
|
||||||
DATA(insert ( 1700 25 1688 i ));
|
DATA(insert ( 1700 25 1688 i ));
|
||||||
DATA(insert ( 25 1700 1686 e ));
|
DATA(insert ( 25 1700 1686 e ));
|
||||||
|
DATA(insert ( 142 25 0 e ));
|
||||||
|
DATA(insert ( 25 142 2896 e ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cross-category casts to and from VARCHAR
|
* Cross-category casts to and from VARCHAR
|
||||||
@ -338,6 +340,8 @@ DATA(insert ( 1266 1043 939 a ));
|
|||||||
DATA(insert ( 1043 1266 938 e ));
|
DATA(insert ( 1043 1266 938 e ));
|
||||||
DATA(insert ( 1700 1043 1688 a ));
|
DATA(insert ( 1700 1043 1688 a ));
|
||||||
DATA(insert ( 1043 1700 1686 e ));
|
DATA(insert ( 1043 1700 1686 e ));
|
||||||
|
DATA(insert ( 142 1043 0 e ));
|
||||||
|
DATA(insert ( 1043 142 2896 e ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cross-category casts to and from BPCHAR
|
* Cross-category casts to and from BPCHAR
|
||||||
@ -377,6 +381,7 @@ DATA(insert ( 1266 1042 939 a ));
|
|||||||
DATA(insert ( 1042 1266 938 e ));
|
DATA(insert ( 1042 1266 938 e ));
|
||||||
DATA(insert ( 1700 1042 1688 a ));
|
DATA(insert ( 1700 1042 1688 a ));
|
||||||
DATA(insert ( 1042 1700 1686 e ));
|
DATA(insert ( 1042 1700 1686 e ));
|
||||||
|
DATA(insert ( 142 1042 0 e ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Length-coercion functions
|
* Length-coercion functions
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.430 2006/12/06 18:06:47 neilc Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.431 2006/12/21 16:05:15 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -3976,6 +3976,26 @@ DESCR("release shared advisory lock");
|
|||||||
DATA(insert OID = 2892 ( pg_advisory_unlock_all PGNSP PGUID 12 f f t f v 0 2278 "" _null_ _null_ _null_ pg_advisory_unlock_all - _null_ ));
|
DATA(insert OID = 2892 ( pg_advisory_unlock_all PGNSP PGUID 12 f f t f v 0 2278 "" _null_ _null_ _null_ pg_advisory_unlock_all - _null_ ));
|
||||||
DESCR("release all advisory locks");
|
DESCR("release all advisory locks");
|
||||||
|
|
||||||
|
/* XML support */
|
||||||
|
DATA(insert OID = 2893 ( xml_in PGNSP PGUID 12 f f t f i 1 142 "2275" _null_ _null_ _null_ xml_in - _null_ ));
|
||||||
|
DESCR("I/O");
|
||||||
|
DATA(insert OID = 2894 ( xml_out PGNSP PGUID 12 f f t f i 1 2275 "142" _null_ _null_ _null_ xml_out - _null_ ));
|
||||||
|
DESCR("I/O");
|
||||||
|
DATA(insert OID = 2895 ( xmlcomment PGNSP PGUID 12 f f t f i 1 142 "25" _null_ _null_ _null_ xmlcomment - _null_ ));
|
||||||
|
DESCR("generate an XML comment");
|
||||||
|
DATA(insert OID = 2896 ( xmlparse PGNSP PGUID 12 f f t f i 1 142 "25" _null_ _null_ _null_ xmlparse - _null_ ));
|
||||||
|
DESCR("perform a non-validating parse of a character string to produce an XML value");
|
||||||
|
DATA(insert OID = 2897 ( xmlparse PGNSP PGUID 12 f f t f i 3 142 "25 16 16" _null_ _null_ _null_ xmlparse - _null_ ));
|
||||||
|
DESCR("perform a non-validating parse of a character string to produce an XML value");
|
||||||
|
DATA(insert OID = 2898 ( xmlpi PGNSP PGUID 12 f f t f i 1 142 "19" _null_ _null_ _null_ xmlpi - _null_ ));
|
||||||
|
DESCR("generate an XML processing instruction");
|
||||||
|
DATA(insert OID = 2899 ( xmlpi PGNSP PGUID 12 f f t f i 2 142 "19 25" _null_ _null_ _null_ xmlpi - _null_ ));
|
||||||
|
DESCR("generate an XML processing instruction");
|
||||||
|
DATA(insert OID = 2900 ( xmlroot PGNSP PGUID 12 f f f f i 3 142 "142 25 16" _null_ _null_ _null_ xmlroot - _null_ ));
|
||||||
|
DESCR("create an XML value by modifying the properties of the XML root information item of another XML value");
|
||||||
|
DATA(insert OID = 2901 ( xmlvalidate PGNSP PGUID 12 f f t f i 2 16 "142 25" _null_ _null_ _null_ xmlvalidate - _null_ ));
|
||||||
|
DESCR("validate an XML value");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Symbolic values for provolatile column: these indicate whether the result
|
* Symbolic values for provolatile column: these indicate whether the result
|
||||||
* of a function is dependent *only* on the values of its explicit arguments,
|
* of a function is dependent *only* on the values of its explicit arguments,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.172 2006/10/04 00:30:08 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.173 2006/12/21 16:05:15 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -316,6 +316,10 @@ DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c t \054 1259 0 record_in reco
|
|||||||
#define PG_CLASS_RELTYPE_OID 83
|
#define PG_CLASS_RELTYPE_OID 83
|
||||||
|
|
||||||
/* OIDS 100 - 199 */
|
/* OIDS 100 - 199 */
|
||||||
|
DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b t \054 0 0 xml_in xml_out - - - i x f 0 -1 0 _null_ _null_ ));
|
||||||
|
DESCR("XML content");
|
||||||
|
#define XMLOID 142
|
||||||
|
DATA(insert OID = 143 ( _xml PGNSP PGUID -1 f b t \054 0 142 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
|
||||||
|
|
||||||
/* OIDS 200 - 299 */
|
/* OIDS 200 - 299 */
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.162 2006/12/04 02:06:55 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.163 2006/12/21 16:05:16 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -723,6 +723,22 @@ typedef struct NullTestState
|
|||||||
TupleDesc argdesc; /* tupdesc for most recent input */
|
TupleDesc argdesc; /* tupdesc for most recent input */
|
||||||
} NullTestState;
|
} NullTestState;
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* XmlExprState node
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
typedef struct XmlExprState
|
||||||
|
{
|
||||||
|
ExprState xprstate;
|
||||||
|
XmlExprOp op;
|
||||||
|
char *name;
|
||||||
|
List *named_args;
|
||||||
|
List *args;
|
||||||
|
Oid *named_args_tcache;
|
||||||
|
char **named_args_ncache;
|
||||||
|
Oid arg_typeout;
|
||||||
|
} XmlExprState;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* CoerceToDomainState node
|
* CoerceToDomainState node
|
||||||
* ----------------
|
* ----------------
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.188 2006/09/28 20:51:42 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.189 2006/12/21 16:05:16 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -140,6 +140,7 @@ typedef enum NodeTag
|
|||||||
T_RangeTblRef,
|
T_RangeTblRef,
|
||||||
T_JoinExpr,
|
T_JoinExpr,
|
||||||
T_FromExpr,
|
T_FromExpr,
|
||||||
|
T_XmlExpr,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TAGS FOR EXPRESSION STATE NODES (execnodes.h)
|
* TAGS FOR EXPRESSION STATE NODES (execnodes.h)
|
||||||
@ -168,6 +169,7 @@ typedef enum NodeTag
|
|||||||
T_NullTestState,
|
T_NullTestState,
|
||||||
T_CoerceToDomainState,
|
T_CoerceToDomainState,
|
||||||
T_DomainConstraintState,
|
T_DomainConstraintState,
|
||||||
|
T_XmlExprState,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TAGS FOR PLANNER NODES (relation.h)
|
* TAGS FOR PLANNER NODES (relation.h)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.118 2006/12/10 22:13:27 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.119 2006/12/21 16:05:16 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -765,6 +765,26 @@ typedef struct BooleanTest
|
|||||||
BoolTestType booltesttype; /* test type */
|
BoolTestType booltesttype; /* test type */
|
||||||
} BooleanTest;
|
} BooleanTest;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XmlExpr - holder for SQL/XML functions XMLCONCAT,
|
||||||
|
* XMLELEMENT, XMLFOREST
|
||||||
|
*/
|
||||||
|
typedef enum XmlExprOp
|
||||||
|
{
|
||||||
|
IS_XMLCONCAT,
|
||||||
|
IS_XMLELEMENT,
|
||||||
|
IS_XMLFOREST,
|
||||||
|
} XmlExprOp;
|
||||||
|
|
||||||
|
typedef struct XmlExpr
|
||||||
|
{
|
||||||
|
Expr xpr;
|
||||||
|
XmlExprOp op; /* xml expression type */
|
||||||
|
char *name; /* element name */
|
||||||
|
List *named_args;
|
||||||
|
List *args;
|
||||||
|
} XmlExpr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CoerceToDomain
|
* CoerceToDomain
|
||||||
*
|
*
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/parser/parse_coerce.h,v 1.66 2006/10/04 00:30:09 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/parser/parse_coerce.h,v 1.67 2006/12/21 16:05:16 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -59,6 +59,8 @@ extern Node *coerce_to_integer(ParseState *pstate, Node *node,
|
|||||||
const char *constructName);
|
const char *constructName);
|
||||||
extern Node *coerce_to_bigint(ParseState *pstate, Node *node,
|
extern Node *coerce_to_bigint(ParseState *pstate, Node *node,
|
||||||
const char *constructName);
|
const char *constructName);
|
||||||
|
extern Node *coerce_to_xml(ParseState *pstate, Node *node,
|
||||||
|
const char *constructName);
|
||||||
|
|
||||||
extern Oid select_common_type(List *typeids, const char *context);
|
extern Oid select_common_type(List *typeids, const char *context);
|
||||||
extern Node *coerce_to_common_type(ParseState *pstate, Node *node,
|
extern Node *coerce_to_common_type(ParseState *pstate, Node *node,
|
||||||
|
@ -251,6 +251,9 @@
|
|||||||
/* Define to 1 if you have the `wldap32' library (-lwldap32). */
|
/* Define to 1 if you have the `wldap32' library (-lwldap32). */
|
||||||
#undef HAVE_LIBWLDAP32
|
#undef HAVE_LIBWLDAP32
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `xml2' library (-lxml2). */
|
||||||
|
#undef HAVE_LIBXML2
|
||||||
|
|
||||||
/* Define to 1 if you have the `z' library (-lz). */
|
/* Define to 1 if you have the `z' library (-lz). */
|
||||||
#undef HAVE_LIBZ
|
#undef HAVE_LIBZ
|
||||||
|
|
||||||
@ -627,6 +630,9 @@
|
|||||||
/* Define to 1 to build with LDAP support. (--with-ldap) */
|
/* Define to 1 to build with LDAP support. (--with-ldap) */
|
||||||
#undef USE_LDAP
|
#undef USE_LDAP
|
||||||
|
|
||||||
|
/* Define to 1 to build with XML support. (--with-libxml) */
|
||||||
|
#undef USE_LIBXML
|
||||||
|
|
||||||
/* Define to select named POSIX semaphores. */
|
/* Define to select named POSIX semaphores. */
|
||||||
#undef USE_NAMED_POSIX_SEMAPHORES
|
#undef USE_NAMED_POSIX_SEMAPHORES
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2003-2006, PostgreSQL Global Development Group
|
* Copyright (c) 2003-2006, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.20 2006/06/16 23:29:26 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.21 2006/12/21 16:05:16 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -148,6 +148,10 @@
|
|||||||
#define ERRCODE_INVALID_BINARY_REPRESENTATION MAKE_SQLSTATE('2','2', 'P','0','3')
|
#define ERRCODE_INVALID_BINARY_REPRESENTATION MAKE_SQLSTATE('2','2', 'P','0','3')
|
||||||
#define ERRCODE_BAD_COPY_FILE_FORMAT MAKE_SQLSTATE('2','2', 'P','0','4')
|
#define ERRCODE_BAD_COPY_FILE_FORMAT MAKE_SQLSTATE('2','2', 'P','0','4')
|
||||||
#define ERRCODE_UNTRANSLATABLE_CHARACTER MAKE_SQLSTATE('2','2', 'P','0','5')
|
#define ERRCODE_UNTRANSLATABLE_CHARACTER MAKE_SQLSTATE('2','2', 'P','0','5')
|
||||||
|
#define ERRCODE_INVALID_XML_DOCUMENT MAKE_SQLSTATE('2', '2', '0', '0', 'M')
|
||||||
|
#define ERRCODE_INVALID_XML_CONTENT MAKE_SQLSTATE('2', '2', '0', '0', 'N')
|
||||||
|
#define ERRCODE_INVALID_XML_COMMENT MAKE_SQLSTATE('2', '2', '0', '0', 'S')
|
||||||
|
#define ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION MAKE_SQLSTATE('2', '2', '0', '0', 'T')
|
||||||
|
|
||||||
/* Class 23 - Integrity Constraint Violation */
|
/* Class 23 - Integrity Constraint Violation */
|
||||||
#define ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION MAKE_SQLSTATE('2','3', '0','0','0')
|
#define ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION MAKE_SQLSTATE('2','3', '0','0','0')
|
||||||
|
37
src/include/utils/xml.h
Normal file
37
src/include/utils/xml.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* xml.h
|
||||||
|
* Declarations for XML data type support.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.1 2006/12/21 16:05:16 petere Exp $
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XML_H
|
||||||
|
#define XML_H
|
||||||
|
|
||||||
|
#include "fmgr.h"
|
||||||
|
|
||||||
|
typedef struct varlena xmltype;
|
||||||
|
|
||||||
|
#define DatumGetXmlP(X) ((xmltype *) PG_DETOAST_DATUM(X))
|
||||||
|
|
||||||
|
#define PG_GETARG_XML_P(n) DatumGetXmlP(PG_GETARG_DATUM(n))
|
||||||
|
#define PG_RETURN_XML_P(x) PG_RETURN_POINTER(x)
|
||||||
|
|
||||||
|
extern Datum xml_in(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum xml_out(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum xmlcomment(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum xmlparse(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum xmlpi(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum xmlroot(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum xmlvalidate(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
|
extern char *map_sql_identifier_to_xml_name(unsigned char *ident, bool fully_escaped);
|
||||||
|
|
||||||
|
#endif /* XML_H */
|
@ -73,7 +73,7 @@ WHERE p1.oid != p2.oid AND
|
|||||||
SELECT p1.oid, p1.proname, p2.oid, p2.proname
|
SELECT p1.oid, p1.proname, p2.oid, p2.proname
|
||||||
FROM pg_proc AS p1, pg_proc AS p2
|
FROM pg_proc AS p1, pg_proc AS p2
|
||||||
WHERE p1.oid < p2.oid AND
|
WHERE p1.oid < p2.oid AND
|
||||||
p1.prosrc = p2.prosrc AND
|
p1.prosrc = p2.prosrc AND p1.prosrc NOT IN ('xmlparse', 'xmlpi') AND
|
||||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||||
(p1.proisagg = false OR p2.proisagg = false) AND
|
(p1.proisagg = false OR p2.proisagg = false) AND
|
||||||
(p1.prolang != p2.prolang OR
|
(p1.prolang != p2.prolang OR
|
||||||
@ -285,6 +285,8 @@ WHERE c.castfunc = p.oid AND
|
|||||||
-- those are binary-compatible while the reverse way goes through rtrim().
|
-- those are binary-compatible while the reverse way goes through rtrim().
|
||||||
-- As of 8.2, this finds the cast from cidr to inet, because that is a
|
-- As of 8.2, this finds the cast from cidr to inet, because that is a
|
||||||
-- trivial binary coercion while the other way goes through inet_to_cidr().
|
-- trivial binary coercion while the other way goes through inet_to_cidr().
|
||||||
|
-- As of 8.3, this finds casts from xml to text, varchar, and bpchar,
|
||||||
|
-- because the other direction has to go through xmlparse().
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM pg_cast c
|
FROM pg_cast c
|
||||||
WHERE c.castfunc = 0 AND
|
WHERE c.castfunc = 0 AND
|
||||||
@ -297,7 +299,10 @@ WHERE c.castfunc = 0 AND
|
|||||||
25 | 1042 | 0 | i
|
25 | 1042 | 0 | i
|
||||||
1043 | 1042 | 0 | i
|
1043 | 1042 | 0 | i
|
||||||
650 | 869 | 0 | i
|
650 | 869 | 0 | i
|
||||||
(3 rows)
|
142 | 25 | 0 | e
|
||||||
|
142 | 1043 | 0 | e
|
||||||
|
142 | 1042 | 0 | e
|
||||||
|
(6 rows)
|
||||||
|
|
||||||
-- **************** pg_operator ****************
|
-- **************** pg_operator ****************
|
||||||
-- Look for illegal values in pg_operator fields.
|
-- Look for illegal values in pg_operator fields.
|
||||||
|
@ -160,7 +160,7 @@ SELECT name, statement, parameter_types FROM pg_prepared_statements
|
|||||||
: \x09ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int);
|
: \x09ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int);
|
||||||
q5 | PREPARE q5(int, text) AS | {integer,text}
|
q5 | PREPARE q5(int, text) AS | {integer,text}
|
||||||
: \x09SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2;
|
: \x09SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2;
|
||||||
q6 | PREPARE q6 AS | {integer,name}
|
q6 | PREPARE q6 AS | {integer,"\"name\""}
|
||||||
: SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2;
|
: SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2;
|
||||||
q7 | PREPARE q7(unknown) AS | {path}
|
q7 | PREPARE q7(unknown) AS | {path}
|
||||||
: SELECT * FROM road WHERE thepath = $1;
|
: SELECT * FROM road WHERE thepath = $1;
|
||||||
|
@ -1276,38 +1276,38 @@ drop table cchild;
|
|||||||
SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schema' ORDER BY viewname;
|
SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schema' ORDER BY viewname;
|
||||||
viewname | definition
|
viewname | definition
|
||||||
--------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
--------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
iexit | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath);
|
iexit | SELECT ih."name", ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath);
|
||||||
pg_cursors | SELECT c.name, c."statement", c.is_holdable, c.is_binary, c.is_scrollable, c.creation_time FROM pg_cursor() c(name text, "statement" text, is_holdable boolean, is_binary boolean, is_scrollable boolean, creation_time timestamp with time zone);
|
pg_cursors | SELECT c."name", c."statement", c.is_holdable, c.is_binary, c.is_scrollable, c.creation_time FROM pg_cursor() c("name" text, "statement" text, is_holdable boolean, is_binary boolean, is_scrollable boolean, creation_time timestamp with time zone);
|
||||||
pg_group | SELECT pg_authid.rolname AS groname, pg_authid.oid AS grosysid, ARRAY(SELECT pg_auth_members.member FROM pg_auth_members WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist FROM pg_authid WHERE (NOT pg_authid.rolcanlogin);
|
pg_group | SELECT pg_authid.rolname AS groname, pg_authid.oid AS grosysid, ARRAY(SELECT pg_auth_members.member FROM pg_auth_members WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist FROM pg_authid WHERE (NOT pg_authid.rolcanlogin);
|
||||||
pg_indexes | SELECT n.nspname AS schemaname, c.relname AS tablename, i.relname AS indexname, t.spcname AS "tablespace", pg_get_indexdef(i.oid) AS indexdef FROM ((((pg_index x JOIN pg_class c ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = i.reltablespace))) WHERE ((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char"));
|
pg_indexes | SELECT n.nspname AS schemaname, c.relname AS tablename, i.relname AS indexname, t.spcname AS "tablespace", pg_get_indexdef(i.oid) AS indexdef FROM ((((pg_index x JOIN pg_class c ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = i.reltablespace))) WHERE ((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char"));
|
||||||
pg_locks | SELECT l.locktype, l."database", l.relation, l.page, l.tuple, l.transactionid, l.classid, l.objid, l.objsubid, l."transaction", l.pid, l."mode", l."granted" FROM pg_lock_status() l(locktype text, "database" oid, relation oid, page integer, tuple smallint, transactionid xid, classid oid, objid oid, objsubid smallint, "transaction" xid, pid integer, "mode" text, "granted" boolean);
|
pg_locks | SELECT l.locktype, l."database", l.relation, l.page, l.tuple, l.transactionid, l.classid, l.objid, l.objsubid, l."transaction", l.pid, l."mode", l."granted" FROM pg_lock_status() l(locktype text, "database" oid, relation oid, page integer, tuple smallint, transactionid xid, classid oid, objid oid, objsubid smallint, "transaction" xid, pid integer, "mode" text, "granted" boolean);
|
||||||
pg_prepared_statements | SELECT p.name, p."statement", p.prepare_time, p.parameter_types, p.from_sql FROM pg_prepared_statement() p(name text, "statement" text, prepare_time timestamp with time zone, parameter_types regtype[], from_sql boolean);
|
pg_prepared_statements | SELECT p."name", p."statement", p.prepare_time, p.parameter_types, p.from_sql FROM pg_prepared_statement() p("name" text, "statement" text, prepare_time timestamp with time zone, parameter_types regtype[], from_sql boolean);
|
||||||
pg_prepared_xacts | SELECT p."transaction", p.gid, p."prepared", u.rolname AS "owner", d.datname AS "database" FROM ((pg_prepared_xact() p("transaction" xid, gid text, "prepared" timestamp with time zone, ownerid oid, dbid oid) LEFT JOIN pg_authid u ON ((p.ownerid = u.oid))) LEFT JOIN pg_database d ON ((p.dbid = d.oid)));
|
pg_prepared_xacts | SELECT p."transaction", p.gid, p."prepared", u.rolname AS "owner", d.datname AS "database" FROM ((pg_prepared_xact() p("transaction" xid, gid text, "prepared" timestamp with time zone, ownerid oid, dbid oid) LEFT JOIN pg_authid u ON ((p.ownerid = u.oid))) LEFT JOIN pg_database d ON ((p.dbid = d.oid)));
|
||||||
pg_roles | SELECT pg_authid.rolname, pg_authid.rolsuper, pg_authid.rolinherit, pg_authid.rolcreaterole, pg_authid.rolcreatedb, pg_authid.rolcatupdate, pg_authid.rolcanlogin, pg_authid.rolconnlimit, '********'::text AS rolpassword, pg_authid.rolvaliduntil, pg_authid.rolconfig, pg_authid.oid FROM pg_authid;
|
pg_roles | SELECT pg_authid.rolname, pg_authid.rolsuper, pg_authid.rolinherit, pg_authid.rolcreaterole, pg_authid.rolcreatedb, pg_authid.rolcatupdate, pg_authid.rolcanlogin, pg_authid.rolconnlimit, '********'::text AS rolpassword, pg_authid.rolvaliduntil, pg_authid.rolconfig, pg_authid.oid FROM pg_authid;
|
||||||
pg_rules | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name);
|
pg_rules | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::"name");
|
||||||
pg_settings | SELECT a.name, a.setting, a.unit, a.category, a.short_desc, a.extra_desc, a.context, a.vartype, a.source, a.min_val, a.max_val FROM pg_show_all_settings() a(name text, setting text, unit text, category text, short_desc text, extra_desc text, context text, vartype text, source text, min_val text, max_val text);
|
pg_settings | SELECT a."name", a.setting, a.unit, a.category, a.short_desc, a.extra_desc, a.context, a.vartype, a.source, a.min_val, a.max_val FROM pg_show_all_settings() a("name" text, setting text, unit text, category text, short_desc text, extra_desc text, context text, vartype text, source text, min_val text, max_val text);
|
||||||
pg_shadow | SELECT pg_authid.rolname AS usename, pg_authid.oid AS usesysid, pg_authid.rolcreatedb AS usecreatedb, pg_authid.rolsuper AS usesuper, pg_authid.rolcatupdate AS usecatupd, pg_authid.rolpassword AS passwd, (pg_authid.rolvaliduntil)::abstime AS valuntil, pg_authid.rolconfig AS useconfig FROM pg_authid WHERE pg_authid.rolcanlogin;
|
pg_shadow | SELECT pg_authid.rolname AS usename, pg_authid.oid AS usesysid, pg_authid.rolcreatedb AS usecreatedb, pg_authid.rolsuper AS usesuper, pg_authid.rolcatupdate AS usecatupd, pg_authid.rolpassword AS passwd, (pg_authid.rolvaliduntil)::abstime AS valuntil, pg_authid.rolconfig AS useconfig FROM pg_authid WHERE pg_authid.rolcanlogin;
|
||||||
pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.rolname AS usename, pg_stat_get_backend_activity(s.backendid) AS current_query, pg_stat_get_backend_waiting(s.backendid) AS waiting, pg_stat_get_backend_txn_start(s.backendid) AS txn_start, pg_stat_get_backend_activity_start(s.backendid) AS query_start, pg_stat_get_backend_start(s.backendid) AS backend_start, pg_stat_get_backend_client_addr(s.backendid) AS client_addr, pg_stat_get_backend_client_port(s.backendid) AS client_port FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_authid u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.oid));
|
pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.rolname AS usename, pg_stat_get_backend_activity(s.backendid) AS current_query, pg_stat_get_backend_waiting(s.backendid) AS waiting, pg_stat_get_backend_txn_start(s.backendid) AS txn_start, pg_stat_get_backend_activity_start(s.backendid) AS query_start, pg_stat_get_backend_start(s.backendid) AS backend_start, pg_stat_get_backend_client_addr(s.backendid) AS client_addr, pg_stat_get_backend_client_port(s.backendid) AS client_port FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_authid u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.oid));
|
||||||
pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"]));
|
pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"]));
|
||||||
pg_stat_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, (sum(pg_stat_get_numscans(i.indexrelid)))::bigint AS idx_scan, ((sum(pg_stat_get_tuples_fetched(i.indexrelid)))::bigint + pg_stat_get_tuples_fetched(c.oid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del, pg_stat_get_last_vacuum_time(c.oid) AS last_vacuum, pg_stat_get_last_autovacuum_time(c.oid) AS last_autovacuum, pg_stat_get_last_analyze_time(c.oid) AS last_analyze, pg_stat_get_last_autoanalyze_time(c.oid) AS last_autoanalyze FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname;
|
pg_stat_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, (sum(pg_stat_get_numscans(i.indexrelid)))::bigint AS idx_scan, ((sum(pg_stat_get_tuples_fetched(i.indexrelid)))::bigint + pg_stat_get_tuples_fetched(c.oid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del, pg_stat_get_last_vacuum_time(c.oid) AS last_vacuum, pg_stat_get_last_autovacuum_time(c.oid) AS last_autovacuum, pg_stat_get_last_analyze_time(c.oid) AS last_analyze, pg_stat_get_last_autoanalyze_time(c.oid) AS last_autoanalyze FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname;
|
||||||
pg_stat_database | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d;
|
pg_stat_database | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d;
|
||||||
pg_stat_sys_indexes | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
|
pg_stat_sys_indexes | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));
|
||||||
pg_stat_sys_tables | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
|
pg_stat_sys_tables | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname = ANY (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));
|
||||||
pg_stat_user_indexes | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
|
pg_stat_user_indexes | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE (pg_stat_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));
|
||||||
pg_stat_user_tables | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
|
pg_stat_user_tables | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del, pg_stat_all_tables.last_vacuum, pg_stat_all_tables.last_autovacuum, pg_stat_all_tables.last_analyze, pg_stat_all_tables.last_autoanalyze FROM pg_stat_all_tables WHERE (pg_stat_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));
|
||||||
pg_statio_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, (pg_stat_get_blocks_fetched(i.oid) - pg_stat_get_blocks_hit(i.oid)) AS idx_blks_read, pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"]));
|
pg_statio_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, (pg_stat_get_blocks_fetched(i.oid) - pg_stat_get_blocks_hit(i.oid)) AS idx_blks_read, pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"]));
|
||||||
pg_statio_all_sequences | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS blks_read, pg_stat_get_blocks_hit(c.oid) AS blks_hit FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'S'::"char");
|
pg_statio_all_sequences | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS blks_read, pg_stat_get_blocks_hit(c.oid) AS blks_hit FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'S'::"char");
|
||||||
pg_statio_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS heap_blks_read, pg_stat_get_blocks_hit(c.oid) AS heap_blks_hit, (sum((pg_stat_get_blocks_fetched(i.indexrelid) - pg_stat_get_blocks_hit(i.indexrelid))))::bigint AS idx_blks_read, (sum(pg_stat_get_blocks_hit(i.indexrelid)))::bigint AS idx_blks_hit, (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read, pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit, (pg_stat_get_blocks_fetched(x.oid) - pg_stat_get_blocks_hit(x.oid)) AS tidx_blks_read, pg_stat_get_blocks_hit(x.oid) AS tidx_blks_hit FROM ((((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid))) LEFT JOIN pg_class x ON ((t.reltoastidxid = x.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
|
pg_statio_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS heap_blks_read, pg_stat_get_blocks_hit(c.oid) AS heap_blks_hit, (sum((pg_stat_get_blocks_fetched(i.indexrelid) - pg_stat_get_blocks_hit(i.indexrelid))))::bigint AS idx_blks_read, (sum(pg_stat_get_blocks_hit(i.indexrelid)))::bigint AS idx_blks_hit, (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read, pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit, (pg_stat_get_blocks_fetched(x.oid) - pg_stat_get_blocks_hit(x.oid)) AS tidx_blks_read, pg_stat_get_blocks_hit(x.oid) AS tidx_blks_hit FROM ((((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid))) LEFT JOIN pg_class x ON ((t.reltoastidxid = x.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])) GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
|
||||||
pg_statio_sys_indexes | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (pg_statio_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
|
pg_statio_sys_indexes | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (pg_statio_all_indexes.schemaname = ANY (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));
|
||||||
pg_statio_sys_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (pg_statio_all_sequences.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
|
pg_statio_sys_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (pg_statio_all_sequences.schemaname = ANY (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));
|
||||||
pg_statio_sys_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.schemaname = ANY (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
|
pg_statio_sys_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.schemaname = ANY (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));
|
||||||
pg_statio_user_indexes | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (pg_statio_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
|
pg_statio_user_indexes | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (pg_statio_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));
|
||||||
pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (pg_statio_all_sequences.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
|
pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (pg_statio_all_sequences.schemaname <> ALL (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));
|
||||||
pg_statio_user_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
|
pg_statio_user_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::"name", 'pg_toast'::"name", 'information_schema'::"name"]));
|
||||||
pg_stats | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE 1 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::anyarray END AS most_common_vals, CASE 1 WHEN s.stakind1 THEN s.stanumbers1 WHEN s.stakind2 THEN s.stanumbers2 WHEN s.stakind3 THEN s.stanumbers3 WHEN s.stakind4 THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE 2 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::anyarray END AS histogram_bounds, CASE 3 WHEN s.stakind1 THEN s.stanumbers1[1] WHEN s.stakind2 THEN s.stanumbers2[1] WHEN s.stakind3 THEN s.stanumbers3[1] WHEN s.stakind4 THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE has_table_privilege(c.oid, 'select'::text);
|
pg_stats | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE 1 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::anyarray END AS most_common_vals, CASE 1 WHEN s.stakind1 THEN s.stanumbers1 WHEN s.stakind2 THEN s.stanumbers2 WHEN s.stakind3 THEN s.stanumbers3 WHEN s.stakind4 THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE 2 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::anyarray END AS histogram_bounds, CASE 3 WHEN s.stakind1 THEN s.stanumbers1[1] WHEN s.stakind2 THEN s.stanumbers2[1] WHEN s.stakind3 THEN s.stanumbers3[1] WHEN s.stakind4 THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE has_table_privilege(c.oid, 'select'::text);
|
||||||
pg_tables | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS "tablespace", c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM ((pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace))) WHERE (c.relkind = 'r'::"char");
|
pg_tables | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS "tablespace", c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM ((pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace))) WHERE (c.relkind = 'r'::"char");
|
||||||
pg_timezone_abbrevs | SELECT pg_timezone_abbrevs.abbrev, pg_timezone_abbrevs.utc_offset, pg_timezone_abbrevs.is_dst FROM pg_timezone_abbrevs() pg_timezone_abbrevs(abbrev, utc_offset, is_dst);
|
pg_timezone_abbrevs | SELECT pg_timezone_abbrevs.abbrev, pg_timezone_abbrevs.utc_offset, pg_timezone_abbrevs.is_dst FROM pg_timezone_abbrevs() pg_timezone_abbrevs(abbrev, utc_offset, is_dst);
|
||||||
pg_timezone_names | SELECT pg_timezone_names.name, pg_timezone_names.abbrev, pg_timezone_names.utc_offset, pg_timezone_names.is_dst FROM pg_timezone_names() pg_timezone_names(name, abbrev, utc_offset, is_dst);
|
pg_timezone_names | SELECT pg_timezone_names."name", pg_timezone_names.abbrev, pg_timezone_names.utc_offset, pg_timezone_names.is_dst FROM pg_timezone_names() pg_timezone_names("name", abbrev, utc_offset, is_dst);
|
||||||
pg_user | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil, pg_shadow.useconfig FROM pg_shadow;
|
pg_user | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil, pg_shadow.useconfig FROM pg_shadow;
|
||||||
pg_views | SELECT n.nspname AS schemaname, c.relname AS viewname, pg_get_userbyid(c.relowner) AS viewowner, pg_get_viewdef(c.oid) AS definition FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'v'::"char");
|
pg_views | SELECT n.nspname AS schemaname, c.relname AS viewname, pg_get_userbyid(c.relowner) AS viewowner, pg_get_viewdef(c.oid) AS definition FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'v'::"char");
|
||||||
rtest_v1 | SELECT rtest_t1.a, rtest_t1.b FROM rtest_t1;
|
rtest_v1 | SELECT rtest_t1.a, rtest_t1.b FROM rtest_t1;
|
||||||
@ -1322,16 +1322,16 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
|
|||||||
shoelace | SELECT s.sl_name, s.sl_avail, s.sl_color, s.sl_len, s.sl_unit, (s.sl_len * u.un_fact) AS sl_len_cm FROM shoelace_data s, unit u WHERE (s.sl_unit = u.un_name);
|
shoelace | SELECT s.sl_name, s.sl_avail, s.sl_color, s.sl_len, s.sl_unit, (s.sl_len * u.un_fact) AS sl_len_cm FROM shoelace_data s, unit u WHERE (s.sl_unit = u.un_name);
|
||||||
shoelace_candelete | SELECT shoelace_obsolete.sl_name, shoelace_obsolete.sl_avail, shoelace_obsolete.sl_color, shoelace_obsolete.sl_len, shoelace_obsolete.sl_unit, shoelace_obsolete.sl_len_cm FROM shoelace_obsolete WHERE (shoelace_obsolete.sl_avail = 0);
|
shoelace_candelete | SELECT shoelace_obsolete.sl_name, shoelace_obsolete.sl_avail, shoelace_obsolete.sl_color, shoelace_obsolete.sl_len, shoelace_obsolete.sl_unit, shoelace_obsolete.sl_len_cm FROM shoelace_obsolete WHERE (shoelace_obsolete.sl_avail = 0);
|
||||||
shoelace_obsolete | SELECT shoelace.sl_name, shoelace.sl_avail, shoelace.sl_color, shoelace.sl_len, shoelace.sl_unit, shoelace.sl_len_cm FROM shoelace WHERE (NOT (EXISTS (SELECT shoe.shoename FROM shoe WHERE (shoe.slcolor = shoelace.sl_color))));
|
shoelace_obsolete | SELECT shoelace.sl_name, shoelace.sl_avail, shoelace.sl_color, shoelace.sl_len, shoelace.sl_unit, shoelace.sl_len_cm FROM shoelace WHERE (NOT (EXISTS (SELECT shoe.shoename FROM shoe WHERE (shoe.slcolor = shoelace.sl_color))));
|
||||||
street | SELECT r.name, r.thepath, c.cname FROM ONLY road r, real_city c WHERE (c.outline ## r.thepath);
|
street | SELECT r."name", r.thepath, c.cname FROM ONLY road r, real_city c WHERE (c.outline ## r.thepath);
|
||||||
toyemp | SELECT emp.name, emp.age, emp."location", (12 * emp.salary) AS annualsal FROM emp;
|
toyemp | SELECT emp."name", emp.age, emp."location", (12 * emp.salary) AS annualsal FROM emp;
|
||||||
(48 rows)
|
(48 rows)
|
||||||
|
|
||||||
SELECT tablename, rulename, definition FROM pg_rules
|
SELECT tablename, rulename, definition FROM pg_rules
|
||||||
ORDER BY tablename, rulename;
|
ORDER BY tablename, rulename;
|
||||||
tablename | rulename | definition
|
tablename | rulename | definition
|
||||||
---------------+-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
---------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
pg_settings | pg_settings_n | CREATE RULE pg_settings_n AS ON UPDATE TO pg_settings DO INSTEAD NOTHING;
|
pg_settings | pg_settings_n | CREATE RULE pg_settings_n AS ON UPDATE TO pg_settings DO INSTEAD NOTHING;
|
||||||
pg_settings | pg_settings_u | CREATE RULE pg_settings_u AS ON UPDATE TO pg_settings WHERE (new.name = old.name) DO SELECT set_config(old.name, new.setting, false) AS set_config;
|
pg_settings | pg_settings_u | CREATE RULE pg_settings_u AS ON UPDATE TO pg_settings WHERE (new."name" = old."name") DO SELECT set_config(old."name", new.setting, false) AS set_config;
|
||||||
rtest_emp | rtest_emp_del | CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (old.ename, "current_user"(), 'fired'::bpchar, '$0.00'::money, old.salary);
|
rtest_emp | rtest_emp_del | CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (old.ename, "current_user"(), 'fired'::bpchar, '$0.00'::money, old.salary);
|
||||||
rtest_emp | rtest_emp_ins | CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'hired'::bpchar, new.salary, '$0.00'::money);
|
rtest_emp | rtest_emp_ins | CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'hired'::bpchar, new.salary, '$0.00'::money);
|
||||||
rtest_emp | rtest_emp_upd | CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE (new.salary <> old.salary) DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'honored'::bpchar, new.salary, old.salary);
|
rtest_emp | rtest_emp_upd | CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE (new.salary <> old.salary) DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'honored'::bpchar, new.salary, old.salary);
|
||||||
@ -1357,7 +1357,7 @@ SELECT tablename, rulename, definition FROM pg_rules
|
|||||||
shoelace | shoelace_del | CREATE RULE shoelace_del AS ON DELETE TO shoelace DO INSTEAD DELETE FROM shoelace_data WHERE (shoelace_data.sl_name = old.sl_name);
|
shoelace | shoelace_del | CREATE RULE shoelace_del AS ON DELETE TO shoelace DO INSTEAD DELETE FROM shoelace_data WHERE (shoelace_data.sl_name = old.sl_name);
|
||||||
shoelace | shoelace_ins | CREATE RULE shoelace_ins AS ON INSERT TO shoelace DO INSTEAD INSERT INTO shoelace_data (sl_name, sl_avail, sl_color, sl_len, sl_unit) VALUES (new.sl_name, new.sl_avail, new.sl_color, new.sl_len, new.sl_unit);
|
shoelace | shoelace_ins | CREATE RULE shoelace_ins AS ON INSERT TO shoelace DO INSTEAD INSERT INTO shoelace_data (sl_name, sl_avail, sl_color, sl_len, sl_unit) VALUES (new.sl_name, new.sl_avail, new.sl_color, new.sl_len, new.sl_unit);
|
||||||
shoelace | shoelace_upd | CREATE RULE shoelace_upd AS ON UPDATE TO shoelace DO INSTEAD UPDATE shoelace_data SET sl_name = new.sl_name, sl_avail = new.sl_avail, sl_color = new.sl_color, sl_len = new.sl_len, sl_unit = new.sl_unit WHERE (shoelace_data.sl_name = old.sl_name);
|
shoelace | shoelace_upd | CREATE RULE shoelace_upd AS ON UPDATE TO shoelace DO INSTEAD UPDATE shoelace_data SET sl_name = new.sl_name, sl_avail = new.sl_avail, sl_color = new.sl_color, sl_len = new.sl_len, sl_unit = new.sl_unit WHERE (shoelace_data.sl_name = old.sl_name);
|
||||||
shoelace_data | log_shoelace | CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data WHERE (new.sl_avail <> old.sl_avail) DO INSERT INTO shoelace_log (sl_name, sl_avail, log_who, log_when) VALUES (new.sl_name, new.sl_avail, 'Al Bundy'::name, 'Thu Jan 01 00:00:00 1970'::timestamp without time zone);
|
shoelace_data | log_shoelace | CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data WHERE (new.sl_avail <> old.sl_avail) DO INSERT INTO shoelace_log (sl_name, sl_avail, log_who, log_when) VALUES (new.sl_name, new.sl_avail, 'Al Bundy'::"name", 'Thu Jan 01 00:00:00 1970'::timestamp without time zone);
|
||||||
shoelace_ok | shoelace_ok_ins | CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok DO INSTEAD UPDATE shoelace SET sl_avail = (shoelace.sl_avail + new.ok_quant) WHERE (shoelace.sl_name = new.ok_name);
|
shoelace_ok | shoelace_ok_ins | CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok DO INSTEAD UPDATE shoelace SET sl_avail = (shoelace.sl_avail + new.ok_quant) WHERE (shoelace.sl_name = new.ok_name);
|
||||||
(29 rows)
|
(29 rows)
|
||||||
|
|
||||||
|
145
src/test/regress/expected/xml.out
Normal file
145
src/test/regress/expected/xml.out
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
CREATE TABLE xmltest (
|
||||||
|
id int,
|
||||||
|
data xml
|
||||||
|
);
|
||||||
|
INSERT INTO xmltest VALUES (1, '<value>one</value>');
|
||||||
|
INSERT INTO xmltest VALUES (2, '<value>two</value>');
|
||||||
|
INSERT INTO xmltest VALUES (3, '<wrong');
|
||||||
|
ERROR: could not parse XML data
|
||||||
|
DETAIL: Expected '>'
|
||||||
|
SELECT * FROM xmltest;
|
||||||
|
id | data
|
||||||
|
----+--------------------
|
||||||
|
1 | <value>one</value>
|
||||||
|
2 | <value>two</value>
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT xmlcomment('test');
|
||||||
|
xmlcomment
|
||||||
|
-------------
|
||||||
|
<!--test-->
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlcomment('-test');
|
||||||
|
xmlcomment
|
||||||
|
--------------
|
||||||
|
<!---test-->
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlcomment('test-');
|
||||||
|
ERROR: invalid XML comment
|
||||||
|
SELECT xmlcomment('--test');
|
||||||
|
ERROR: invalid XML comment
|
||||||
|
SELECT xmlcomment('te st');
|
||||||
|
xmlcomment
|
||||||
|
--------------
|
||||||
|
<!--te st-->
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlconcat(xmlcomment('hello'),
|
||||||
|
xmlelement(NAME qux, 'foo'),
|
||||||
|
xmlcomment('world'));
|
||||||
|
xmlconcat
|
||||||
|
----------------------------------------
|
||||||
|
<!--hello--><qux>foo</qux><!--world-->
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlconcat('hello', 'you');
|
||||||
|
xmlconcat
|
||||||
|
-----------
|
||||||
|
helloyou
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlconcat(1, 2);
|
||||||
|
ERROR: argument of XMLCONCAT must be type xml, not type integer
|
||||||
|
SELECT xmlconcat('bad', '<syntax');
|
||||||
|
ERROR: could not parse XML data
|
||||||
|
DETAIL: Expected '>'
|
||||||
|
SELECT xmlelement(name element,
|
||||||
|
xmlattributes (1 as one, 'deuce' as two),
|
||||||
|
'content');
|
||||||
|
xmlelement
|
||||||
|
------------------------------------------------
|
||||||
|
<element one="1" two="deuce">content</element>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlelement(name element,
|
||||||
|
xmlattributes ('unnamed and wrong'));
|
||||||
|
ERROR: unnamed attribute value must be a column reference
|
||||||
|
SELECT xmlelement(name element, xmlelement(name nested, 'stuff'));
|
||||||
|
xmlelement
|
||||||
|
-------------------------------------------
|
||||||
|
<element><nested>stuff</nested></element>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp;
|
||||||
|
xmlelement
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
<employee><name>sharon</name><age>25</age><pay>1000</pay></employee>
|
||||||
|
<employee><name>sam</name><age>30</age><pay>2000</pay></employee>
|
||||||
|
<employee><name>bill</name><age>20</age><pay>1000</pay></employee>
|
||||||
|
<employee><name>jeff</name><age>23</age><pay>600</pay></employee>
|
||||||
|
<employee><name>cim</name><age>30</age><pay>400</pay></employee>
|
||||||
|
<employee><name>linda</name><age>19</age><pay>100</pay></employee>
|
||||||
|
(6 rows)
|
||||||
|
|
||||||
|
SELECT xmlelement(name wrong, 37);
|
||||||
|
ERROR: argument of XMLELEMENT must be type xml, not type integer
|
||||||
|
SELECT xmlpi(name foo);
|
||||||
|
xmlpi
|
||||||
|
---------
|
||||||
|
<?foo?>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlpi(name xmlstuff);
|
||||||
|
ERROR: invalid XML processing instruction
|
||||||
|
DETAIL: XML processing instruction target name cannot start with "xml".
|
||||||
|
SELECT xmlpi(name foo, 'bar');
|
||||||
|
xmlpi
|
||||||
|
-------------
|
||||||
|
<?foo bar?>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlpi(name foo, 'in?>valid');
|
||||||
|
ERROR: invalid XML processing instruction
|
||||||
|
DETAIL: XML processing instruction cannot contain "?>".
|
||||||
|
SELECT xmlroot (
|
||||||
|
xmlelement (
|
||||||
|
name gazonk,
|
||||||
|
xmlattributes (
|
||||||
|
'val' AS name,
|
||||||
|
1 + 1 AS num
|
||||||
|
),
|
||||||
|
xmlelement (
|
||||||
|
NAME qux,
|
||||||
|
'foo'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
version '1.0',
|
||||||
|
standalone yes
|
||||||
|
);
|
||||||
|
xmlroot
|
||||||
|
------------------------------------------------------------------------------------------
|
||||||
|
<?xml version="1.0" standalone="yes"?><gazonk name="val" num="2"><qux>foo</qux></gazonk>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlserialize(content data as character varying) FROM xmltest;
|
||||||
|
data
|
||||||
|
--------------------
|
||||||
|
<value>one</value>
|
||||||
|
<value>two</value>
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- Check mapping SQL identifier to XML name
|
||||||
|
SELECT xmlpi(name ":::_xml_abc135.%-&_");
|
||||||
|
xmlpi
|
||||||
|
-------------------------------------------------
|
||||||
|
<?_x003A_::_x005F_xml_abc135._x0025_-_x0026__?>
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT xmlpi(name "123");
|
||||||
|
xmlpi
|
||||||
|
---------------
|
||||||
|
<?_x0031_23?>
|
||||||
|
(1 row)
|
||||||
|
|
77
src/test/regress/expected/xml_1.out
Normal file
77
src/test/regress/expected/xml_1.out
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
CREATE TABLE xmltest (
|
||||||
|
id int,
|
||||||
|
data xml
|
||||||
|
);
|
||||||
|
INSERT INTO xmltest VALUES (1, '<value>one</value>');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
INSERT INTO xmltest VALUES (2, '<value>two</value>');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
INSERT INTO xmltest VALUES (3, '<wrong');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT * FROM xmltest;
|
||||||
|
id | data
|
||||||
|
----+------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT xmlcomment('test');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlcomment('-test');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlcomment('test-');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlcomment('--test');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlcomment('te st');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlconcat(xmlcomment('hello'),
|
||||||
|
xmlelement(NAME qux, 'foo'),
|
||||||
|
xmlcomment('world'));
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlconcat('hello', 'you');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlconcat(1, 2);
|
||||||
|
ERROR: argument of XMLCONCAT must be type xml, not type integer
|
||||||
|
SELECT xmlconcat('bad', '<syntax');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlelement(name element,
|
||||||
|
xmlattributes (1 as one, 'deuce' as two),
|
||||||
|
'content');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlelement(name element,
|
||||||
|
xmlattributes ('unnamed and wrong'));
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlelement(name element, xmlelement(name nested, 'stuff'));
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp;
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlelement(name wrong, 37);
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlpi(name foo);
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlpi(name xmlstuff);
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlpi(name foo, 'bar');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlpi(name foo, 'in?>valid');
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlroot (
|
||||||
|
xmlelement (
|
||||||
|
name gazonk,
|
||||||
|
xmlattributes (
|
||||||
|
'val' AS name,
|
||||||
|
1 + 1 AS num
|
||||||
|
),
|
||||||
|
xmlelement (
|
||||||
|
NAME qux,
|
||||||
|
'foo'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
version '1.0',
|
||||||
|
standalone yes
|
||||||
|
);
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
-- Check mapping SQL identifier to XML name
|
||||||
|
SELECT xmlpi(name ":::_xml_abc135.%-&_");
|
||||||
|
ERROR: no XML support in this installation
|
||||||
|
SELECT xmlpi(name "123");
|
||||||
|
ERROR: no XML support in this installation
|
@ -1,6 +1,6 @@
|
|||||||
# ----------
|
# ----------
|
||||||
# The first group of parallel test
|
# The first group of parallel test
|
||||||
# $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.35 2006/08/30 23:34:22 tgl Exp $
|
# $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.36 2006/12/21 16:05:16 petere Exp $
|
||||||
# ----------
|
# ----------
|
||||||
test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric
|
test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ test: select_views portals_p2 rules foreign_key cluster dependency guc
|
|||||||
# The sixth group of parallel test
|
# The sixth group of parallel test
|
||||||
# ----------
|
# ----------
|
||||||
# "plpgsql" cannot run concurrently with "rules"
|
# "plpgsql" cannot run concurrently with "rules"
|
||||||
test: limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning
|
test: limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning xml
|
||||||
|
|
||||||
# run stats by itself because its delay may be insufficient under heavy load
|
# run stats by itself because its delay may be insufficient under heavy load
|
||||||
test: stats
|
test: stats
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.33 2006/08/30 23:34:22 tgl Exp $
|
# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.34 2006/12/21 16:05:16 petere Exp $
|
||||||
# This should probably be in an order similar to parallel_schedule.
|
# This should probably be in an order similar to parallel_schedule.
|
||||||
test: boolean
|
test: boolean
|
||||||
test: char
|
test: char
|
||||||
@ -102,5 +102,6 @@ test: sequence
|
|||||||
test: polymorphism
|
test: polymorphism
|
||||||
test: rowtypes
|
test: rowtypes
|
||||||
test: returning
|
test: returning
|
||||||
|
test: xml
|
||||||
test: stats
|
test: stats
|
||||||
test: tablespace
|
test: tablespace
|
||||||
|
@ -76,7 +76,7 @@ WHERE p1.oid != p2.oid AND
|
|||||||
SELECT p1.oid, p1.proname, p2.oid, p2.proname
|
SELECT p1.oid, p1.proname, p2.oid, p2.proname
|
||||||
FROM pg_proc AS p1, pg_proc AS p2
|
FROM pg_proc AS p1, pg_proc AS p2
|
||||||
WHERE p1.oid < p2.oid AND
|
WHERE p1.oid < p2.oid AND
|
||||||
p1.prosrc = p2.prosrc AND
|
p1.prosrc = p2.prosrc AND p1.prosrc NOT IN ('xmlparse', 'xmlpi') AND
|
||||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||||
(p1.proisagg = false OR p2.proisagg = false) AND
|
(p1.proisagg = false OR p2.proisagg = false) AND
|
||||||
(p1.prolang != p2.prolang OR
|
(p1.prolang != p2.prolang OR
|
||||||
@ -235,6 +235,9 @@ WHERE c.castfunc = p.oid AND
|
|||||||
-- As of 8.2, this finds the cast from cidr to inet, because that is a
|
-- As of 8.2, this finds the cast from cidr to inet, because that is a
|
||||||
-- trivial binary coercion while the other way goes through inet_to_cidr().
|
-- trivial binary coercion while the other way goes through inet_to_cidr().
|
||||||
|
|
||||||
|
-- As of 8.3, this finds casts from xml to text, varchar, and bpchar,
|
||||||
|
-- because the other direction has to go through xmlparse().
|
||||||
|
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM pg_cast c
|
FROM pg_cast c
|
||||||
WHERE c.castfunc = 0 AND
|
WHERE c.castfunc = 0 AND
|
||||||
|
72
src/test/regress/sql/xml.sql
Normal file
72
src/test/regress/sql/xml.sql
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
CREATE TABLE xmltest (
|
||||||
|
id int,
|
||||||
|
data xml
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO xmltest VALUES (1, '<value>one</value>');
|
||||||
|
INSERT INTO xmltest VALUES (2, '<value>two</value>');
|
||||||
|
INSERT INTO xmltest VALUES (3, '<wrong');
|
||||||
|
|
||||||
|
SELECT * FROM xmltest;
|
||||||
|
|
||||||
|
|
||||||
|
SELECT xmlcomment('test');
|
||||||
|
SELECT xmlcomment('-test');
|
||||||
|
SELECT xmlcomment('test-');
|
||||||
|
SELECT xmlcomment('--test');
|
||||||
|
SELECT xmlcomment('te st');
|
||||||
|
|
||||||
|
|
||||||
|
SELECT xmlconcat(xmlcomment('hello'),
|
||||||
|
xmlelement(NAME qux, 'foo'),
|
||||||
|
xmlcomment('world'));
|
||||||
|
|
||||||
|
SELECT xmlconcat('hello', 'you');
|
||||||
|
SELECT xmlconcat(1, 2);
|
||||||
|
SELECT xmlconcat('bad', '<syntax');
|
||||||
|
|
||||||
|
|
||||||
|
SELECT xmlelement(name element,
|
||||||
|
xmlattributes (1 as one, 'deuce' as two),
|
||||||
|
'content');
|
||||||
|
|
||||||
|
SELECT xmlelement(name element,
|
||||||
|
xmlattributes ('unnamed and wrong'));
|
||||||
|
|
||||||
|
SELECT xmlelement(name element, xmlelement(name nested, 'stuff'));
|
||||||
|
|
||||||
|
SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp;
|
||||||
|
|
||||||
|
SELECT xmlelement(name wrong, 37);
|
||||||
|
|
||||||
|
|
||||||
|
SELECT xmlpi(name foo);
|
||||||
|
SELECT xmlpi(name xmlstuff);
|
||||||
|
SELECT xmlpi(name foo, 'bar');
|
||||||
|
SELECT xmlpi(name foo, 'in?>valid');
|
||||||
|
|
||||||
|
|
||||||
|
SELECT xmlroot (
|
||||||
|
xmlelement (
|
||||||
|
name gazonk,
|
||||||
|
xmlattributes (
|
||||||
|
'val' AS name,
|
||||||
|
1 + 1 AS num
|
||||||
|
),
|
||||||
|
xmlelement (
|
||||||
|
NAME qux,
|
||||||
|
'foo'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
version '1.0',
|
||||||
|
standalone yes
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
SELECT xmlserialize(content data as character varying) FROM xmltest;
|
||||||
|
|
||||||
|
|
||||||
|
-- Check mapping SQL identifier to XML name
|
||||||
|
|
||||||
|
SELECT xmlpi(name ":::_xml_abc135.%-&_");
|
||||||
|
SELECT xmlpi(name "123");
|
Loading…
x
Reference in New Issue
Block a user