mirror of
https://github.com/postgres/postgres.git
synced 2025-05-01 01:04:50 +03:00
Code review for XML patch. Instill a bit of sanity in the location of
the XmlExpr code in various lists, use a representation that has some hope of reverse-listing correctly (though it's still a de-escaping function shy of correctness), generally try to make it look more like Postgres coding conventions.
This commit is contained in:
parent
64974613c9
commit
c957c0bac7
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.20 2006/06/16 23:29:26 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.21 2006/12/24 00:29:17 tgl Exp $ -->
|
||||||
|
|
||||||
<appendix id="errcodes-appendix">
|
<appendix id="errcodes-appendix">
|
||||||
<title><productname>PostgreSQL</productname> Error Codes</title>
|
<title><productname>PostgreSQL</productname> Error Codes</title>
|
||||||
@ -541,6 +541,29 @@
|
|||||||
<entry>untranslatable_character</entry>
|
<entry>untranslatable_character</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><literal>2200M</literal></entry>
|
||||||
|
<entry>INVALID XML DOCUMENT</entry>
|
||||||
|
<entry>invalid_xml_document</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><literal>2200N</literal></entry>
|
||||||
|
<entry>INVALID XML CONTENT</entry>
|
||||||
|
<entry>invalid_xml_content</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><literal>2200S</literal></entry>
|
||||||
|
<entry>INVALID XML COMMENT</entry>
|
||||||
|
<entry>invalid_xml_comment</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><literal>2200T</literal></entry>
|
||||||
|
<entry>INVALID XML PROCESSING INSTRUCTION</entry>
|
||||||
|
<entry>invalid_xml_processing_instruction</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry spanname="span13"><emphasis role="bold">Class 23 — Integrity Constraint Violation</></entry>
|
<entry spanname="span13"><emphasis role="bold">Class 23 — Integrity Constraint Violation</></entry>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/installation.sgml,v 1.269 2006/12/21 16:05:13 petere Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/installation.sgml,v 1.270 2006/12/24 00:29:17 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="installation">
|
<chapter id="installation">
|
||||||
<title><![%standalone-include[<productname>PostgreSQL</>]]>
|
<title><![%standalone-include[<productname>PostgreSQL</>]]>
|
||||||
@ -909,7 +909,7 @@ su - postgres
|
|||||||
<term><option>--with-libxml</option></term>
|
<term><option>--with-libxml</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Build with libxml, required for SQL/XML support.
|
Build with libxml (enables SQL/XML support).
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.201 2006/12/23 00:43:09 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.202 2006/12/24 00:29:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -117,11 +117,11 @@ static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
|
|||||||
static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
|
static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
|
||||||
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 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);
|
||||||
@ -2638,6 +2638,237 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------
|
||||||
|
* ExecEvalXml
|
||||||
|
* ----------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static Datum
|
||||||
|
ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
|
||||||
|
bool *isNull, ExprDoneCond *isDone)
|
||||||
|
{
|
||||||
|
XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
|
||||||
|
text *result;
|
||||||
|
StringInfoData buf;
|
||||||
|
Datum value;
|
||||||
|
bool isnull;
|
||||||
|
char *str;
|
||||||
|
ListCell *arg;
|
||||||
|
ListCell *narg;
|
||||||
|
bool found_arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (isDone)
|
||||||
|
*isDone = ExprSingleResult;
|
||||||
|
*isNull = true; /* until we get a result */
|
||||||
|
|
||||||
|
switch (xexpr->op)
|
||||||
|
{
|
||||||
|
case IS_XMLCONCAT:
|
||||||
|
initStringInfo(&buf);
|
||||||
|
foreach(arg, xmlExpr->args)
|
||||||
|
{
|
||||||
|
ExprState *e = (ExprState *) lfirst(arg);
|
||||||
|
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (!isnull)
|
||||||
|
{
|
||||||
|
/* we know the value is XML type */
|
||||||
|
str = DatumGetCString(DirectFunctionCall1(xml_out,
|
||||||
|
value));
|
||||||
|
appendStringInfoString(&buf, str);
|
||||||
|
pfree(str);
|
||||||
|
*isNull = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_XMLELEMENT:
|
||||||
|
initStringInfo(&buf);
|
||||||
|
*isNull = false;
|
||||||
|
appendStringInfo(&buf, "<%s", xexpr->name);
|
||||||
|
i = 0;
|
||||||
|
forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
|
||||||
|
{
|
||||||
|
ExprState *e = (ExprState *) lfirst(arg);
|
||||||
|
char *argname = strVal(lfirst(narg));
|
||||||
|
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (!isnull)
|
||||||
|
{
|
||||||
|
str = OutputFunctionCall(&xmlExpr->named_outfuncs[i],
|
||||||
|
value);
|
||||||
|
appendStringInfo(&buf, " %s=\"%s\"", argname, str);
|
||||||
|
pfree(str);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
found_arg = false;
|
||||||
|
foreach(arg, xmlExpr->args)
|
||||||
|
{
|
||||||
|
ExprState *e = (ExprState *) lfirst(arg);
|
||||||
|
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (!isnull)
|
||||||
|
{
|
||||||
|
if (!found_arg)
|
||||||
|
{
|
||||||
|
appendStringInfoChar(&buf, '>');
|
||||||
|
found_arg = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we know the value is XML type */
|
||||||
|
str = DatumGetCString(DirectFunctionCall1(xml_out,
|
||||||
|
value));
|
||||||
|
appendStringInfoString(&buf, str);
|
||||||
|
pfree(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_arg)
|
||||||
|
appendStringInfo(&buf, "/>");
|
||||||
|
else
|
||||||
|
appendStringInfo(&buf, "</%s>", xexpr->name);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_XMLFOREST:
|
||||||
|
initStringInfo(&buf);
|
||||||
|
i = 0;
|
||||||
|
forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
|
||||||
|
{
|
||||||
|
ExprState *e = (ExprState *) lfirst(arg);
|
||||||
|
char *argname = strVal(lfirst(narg));
|
||||||
|
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (!isnull)
|
||||||
|
{
|
||||||
|
str = OutputFunctionCall(&xmlExpr->named_outfuncs[i],
|
||||||
|
value);
|
||||||
|
appendStringInfo(&buf, "<%s>%s</%s>",
|
||||||
|
argname, str, argname);
|
||||||
|
pfree(str);
|
||||||
|
*isNull = false;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* The remaining cases don't need to set up buf */
|
||||||
|
case IS_XMLPARSE:
|
||||||
|
{
|
||||||
|
ExprState *e;
|
||||||
|
text *data;
|
||||||
|
bool is_document;
|
||||||
|
bool preserve_whitespace;
|
||||||
|
|
||||||
|
/* arguments are known to be text, bool, bool */
|
||||||
|
Assert(list_length(xmlExpr->args) == 3);
|
||||||
|
|
||||||
|
e = (ExprState *) linitial(xmlExpr->args);
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (isnull)
|
||||||
|
return (Datum) 0;
|
||||||
|
data = DatumGetTextP(value);
|
||||||
|
|
||||||
|
e = (ExprState *) lsecond(xmlExpr->args);
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (isnull) /* probably can't happen */
|
||||||
|
return (Datum) 0;
|
||||||
|
is_document = DatumGetBool(value);
|
||||||
|
|
||||||
|
e = (ExprState *) lthird(xmlExpr->args);
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (isnull) /* probably can't happen */
|
||||||
|
return (Datum) 0;
|
||||||
|
preserve_whitespace = DatumGetBool(value);
|
||||||
|
|
||||||
|
*isNull = false;
|
||||||
|
|
||||||
|
return PointerGetDatum(xmlparse(data,
|
||||||
|
is_document,
|
||||||
|
preserve_whitespace));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_XMLPI:
|
||||||
|
{
|
||||||
|
ExprState *e;
|
||||||
|
text *arg;
|
||||||
|
|
||||||
|
/* optional argument is known to be text */
|
||||||
|
Assert(list_length(xmlExpr->args) <= 1);
|
||||||
|
|
||||||
|
if (xmlExpr->args)
|
||||||
|
{
|
||||||
|
e = (ExprState *) linitial(xmlExpr->args);
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (isnull)
|
||||||
|
return (Datum) 0;
|
||||||
|
arg = DatumGetTextP(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
arg = NULL;
|
||||||
|
|
||||||
|
*isNull = false;
|
||||||
|
|
||||||
|
return PointerGetDatum(xmlpi(xexpr->name, arg));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_XMLROOT:
|
||||||
|
{
|
||||||
|
ExprState *e;
|
||||||
|
xmltype *data;
|
||||||
|
text *version;
|
||||||
|
int standalone;
|
||||||
|
|
||||||
|
/* arguments are known to be xml, text, bool */
|
||||||
|
Assert(list_length(xmlExpr->args) == 3);
|
||||||
|
|
||||||
|
e = (ExprState *) linitial(xmlExpr->args);
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (isnull)
|
||||||
|
return (Datum) 0;
|
||||||
|
data = DatumGetXmlP(value);
|
||||||
|
|
||||||
|
e = (ExprState *) lsecond(xmlExpr->args);
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (isnull)
|
||||||
|
version = NULL;
|
||||||
|
else
|
||||||
|
version = DatumGetTextP(value);
|
||||||
|
|
||||||
|
e = (ExprState *) lthird(xmlExpr->args);
|
||||||
|
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||||
|
if (isnull)
|
||||||
|
standalone = 0;
|
||||||
|
else
|
||||||
|
standalone = (DatumGetBool(value) ? 1 : -1);
|
||||||
|
|
||||||
|
*isNull = false;
|
||||||
|
|
||||||
|
return PointerGetDatum(xmlroot(data,
|
||||||
|
version,
|
||||||
|
standalone));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*isNull)
|
||||||
|
result = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int len = buf.len + VARHDRSZ;
|
||||||
|
|
||||||
|
result = palloc(len);
|
||||||
|
VARATT_SIZEP(result) = len;
|
||||||
|
memcpy(VARDATA(result), buf.data, buf.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
pfree(buf.data);
|
||||||
|
return PointerGetDatum(result);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
* ExecEvalNullIf
|
* ExecEvalNullIf
|
||||||
*
|
*
|
||||||
@ -2881,120 +3112,6 @@ 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
|
||||||
*
|
*
|
||||||
@ -3794,57 +3911,43 @@ ExecInitExpr(Expr *node, PlanState *parent)
|
|||||||
break;
|
break;
|
||||||
case T_XmlExpr:
|
case T_XmlExpr:
|
||||||
{
|
{
|
||||||
List *outlist;
|
|
||||||
ListCell *arg;
|
|
||||||
XmlExpr *xexpr = (XmlExpr *) node;
|
XmlExpr *xexpr = (XmlExpr *) node;
|
||||||
XmlExprState *xstate = makeNode(XmlExprState);
|
XmlExprState *xstate = makeNode(XmlExprState);
|
||||||
int i = 0;
|
List *outlist;
|
||||||
Oid typeout;
|
ListCell *arg;
|
||||||
|
int i;
|
||||||
xstate->name = xexpr->name;
|
|
||||||
|
|
||||||
xstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalXml;
|
xstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalXml;
|
||||||
xstate->op = xexpr->op;
|
xstate->named_outfuncs = (FmgrInfo *)
|
||||||
|
palloc0(list_length(xexpr->named_args) * sizeof(FmgrInfo));
|
||||||
outlist = NIL;
|
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;
|
i = 0;
|
||||||
foreach(arg, xexpr->named_args)
|
foreach(arg, xexpr->named_args)
|
||||||
{
|
{
|
||||||
bool tpisvarlena;
|
|
||||||
Expr *e = (Expr *) lfirst(arg);
|
Expr *e = (Expr *) lfirst(arg);
|
||||||
ExprState *estate = ExecInitExpr(e, parent);
|
ExprState *estate;
|
||||||
TargetEntry *tle;
|
Oid typOutFunc;
|
||||||
|
bool typIsVarlena;
|
||||||
|
|
||||||
|
estate = ExecInitExpr(e, parent);
|
||||||
outlist = lappend(outlist, estate);
|
outlist = lappend(outlist, estate);
|
||||||
tle = (TargetEntry *) ((GenericExprState *) estate)->xprstate.expr;
|
|
||||||
getTypeOutputInfo(exprType((Node *)tle->expr), &typeout, &tpisvarlena);
|
getTypeOutputInfo(exprType((Node *) e),
|
||||||
xstate->named_args_ncache[i] = tle->resname;
|
&typOutFunc, &typIsVarlena);
|
||||||
xstate->named_args_tcache[i] = typeout;
|
fmgr_info(typOutFunc, &xstate->named_outfuncs[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xstate->named_args_tcache = NULL;
|
|
||||||
xstate->named_args_ncache = NULL;
|
|
||||||
}
|
|
||||||
xstate->named_args = outlist;
|
xstate->named_args = outlist;
|
||||||
|
|
||||||
outlist = NIL;
|
outlist = NIL;
|
||||||
foreach(arg, xexpr->args)
|
foreach(arg, xexpr->args)
|
||||||
{
|
{
|
||||||
bool tpisvarlena;
|
|
||||||
ExprState *estate;
|
|
||||||
Expr *e = (Expr *) lfirst(arg);
|
Expr *e = (Expr *) lfirst(arg);
|
||||||
getTypeOutputInfo(exprType((Node *)e), &typeout, &tpisvarlena);
|
ExprState *estate;
|
||||||
|
|
||||||
estate = ExecInitExpr(e, parent);
|
estate = ExecInitExpr(e, parent);
|
||||||
outlist = lappend(outlist, estate);
|
outlist = lappend(outlist, estate);
|
||||||
}
|
}
|
||||||
xstate->arg_typeout = typeout;
|
|
||||||
xstate->args = outlist;
|
xstate->args = outlist;
|
||||||
|
|
||||||
state = (ExprState *) xstate;
|
state = (ExprState *) xstate;
|
||||||
|
@ -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.356 2006/12/23 00:43:09 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.357 2006/12/24 00:29:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1093,6 +1093,23 @@ _copyMinMaxExpr(MinMaxExpr *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(arg_names);
|
||||||
|
COPY_NODE_FIELD(args);
|
||||||
|
|
||||||
|
return newnode;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _copyNullIfExpr (same as OpExpr)
|
* _copyNullIfExpr (same as OpExpr)
|
||||||
*/
|
*/
|
||||||
@ -1138,22 +1155,6 @@ _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
|
||||||
*/
|
*/
|
||||||
@ -2977,6 +2978,9 @@ copyObject(void *from)
|
|||||||
case T_MinMaxExpr:
|
case T_MinMaxExpr:
|
||||||
retval = _copyMinMaxExpr(from);
|
retval = _copyMinMaxExpr(from);
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
retval = _copyXmlExpr(from);
|
||||||
|
break;
|
||||||
case T_NullIfExpr:
|
case T_NullIfExpr:
|
||||||
retval = _copyNullIfExpr(from);
|
retval = _copyNullIfExpr(from);
|
||||||
break;
|
break;
|
||||||
@ -2986,9 +2990,6 @@ 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.290 2006/12/23 00:43:10 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.291 2006/12/24 00:29:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -454,6 +454,18 @@ _equalMinMaxExpr(MinMaxExpr *a, MinMaxExpr *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(arg_names);
|
||||||
|
COMPARE_NODE_FIELD(args);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_equalNullIfExpr(NullIfExpr *a, NullIfExpr *b)
|
_equalNullIfExpr(NullIfExpr *a, NullIfExpr *b)
|
||||||
{
|
{
|
||||||
@ -495,17 +507,6 @@ _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)
|
||||||
{
|
{
|
||||||
@ -1971,6 +1972,9 @@ equal(void *a, void *b)
|
|||||||
case T_MinMaxExpr:
|
case T_MinMaxExpr:
|
||||||
retval = _equalMinMaxExpr(a, b);
|
retval = _equalMinMaxExpr(a, b);
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
retval = _equalXmlExpr(a, b);
|
||||||
|
break;
|
||||||
case T_NullIfExpr:
|
case T_NullIfExpr:
|
||||||
retval = _equalNullIfExpr(a, b);
|
retval = _equalNullIfExpr(a, b);
|
||||||
break;
|
break;
|
||||||
@ -1980,9 +1984,6 @@ 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.288 2006/12/23 00:43:10 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.289 2006/12/24 00:29:18 tgl 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*
|
||||||
@ -892,6 +892,18 @@ _outMinMaxExpr(StringInfo str, MinMaxExpr *node)
|
|||||||
WRITE_NODE_FIELD(args);
|
WRITE_NODE_FIELD(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(arg_names);
|
||||||
|
WRITE_NODE_FIELD(args);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_outNullIfExpr(StringInfo str, NullIfExpr *node)
|
_outNullIfExpr(StringInfo str, NullIfExpr *node)
|
||||||
{
|
{
|
||||||
@ -922,17 +934,6 @@ _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)
|
||||||
{
|
{
|
||||||
@ -2026,6 +2027,9 @@ _outNode(StringInfo str, void *obj)
|
|||||||
case T_MinMaxExpr:
|
case T_MinMaxExpr:
|
||||||
_outMinMaxExpr(str, obj);
|
_outMinMaxExpr(str, obj);
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
_outXmlExpr(str, obj);
|
||||||
|
break;
|
||||||
case T_NullIfExpr:
|
case T_NullIfExpr:
|
||||||
_outNullIfExpr(str, obj);
|
_outNullIfExpr(str, obj);
|
||||||
break;
|
break;
|
||||||
@ -2035,9 +2039,6 @@ _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.198 2006/12/23 00:43:10 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.199 2006/12/24 00:29:18 tgl 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
|
||||||
@ -708,6 +708,23 @@ _readMinMaxExpr(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(arg_names);
|
||||||
|
READ_NODE_FIELD(args);
|
||||||
|
|
||||||
|
READ_DONE();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _readNullIfExpr
|
* _readNullIfExpr
|
||||||
*/
|
*/
|
||||||
@ -764,22 +781,6 @@ _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
|
||||||
*/
|
*/
|
||||||
@ -1024,14 +1025,14 @@ parseNodeString(void)
|
|||||||
return_value = _readCoalesceExpr();
|
return_value = _readCoalesceExpr();
|
||||||
else if (MATCH("MINMAX", 6))
|
else if (MATCH("MINMAX", 6))
|
||||||
return_value = _readMinMaxExpr();
|
return_value = _readMinMaxExpr();
|
||||||
|
else if (MATCH("XMLEXPR", 7))
|
||||||
|
return_value = _readXmlExpr();
|
||||||
else if (MATCH("NULLIFEXPR", 10))
|
else if (MATCH("NULLIFEXPR", 10))
|
||||||
return_value = _readNullIfExpr();
|
return_value = _readNullIfExpr();
|
||||||
else if (MATCH("NULLTEST", 8))
|
else if (MATCH("NULLTEST", 8))
|
||||||
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.225 2006/12/23 00:43:10 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.226 2006/12/24 00:29:18 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -557,10 +557,10 @@ expression_returns_set_walker(Node *node, void *context)
|
|||||||
return false;
|
return false;
|
||||||
if (IsA(node, MinMaxExpr))
|
if (IsA(node, MinMaxExpr))
|
||||||
return false;
|
return false;
|
||||||
if (IsA(node, NullIfExpr))
|
|
||||||
return false;
|
|
||||||
if (IsA(node, XmlExpr))
|
if (IsA(node, XmlExpr))
|
||||||
return false;
|
return false;
|
||||||
|
if (IsA(node, NullIfExpr))
|
||||||
|
return false;
|
||||||
|
|
||||||
return expression_tree_walker(node, expression_returns_set_walker,
|
return expression_tree_walker(node, expression_returns_set_walker,
|
||||||
context);
|
context);
|
||||||
@ -872,14 +872,14 @@ contain_nonstrict_functions_walker(Node *node, void *context)
|
|||||||
return true;
|
return true;
|
||||||
if (IsA(node, MinMaxExpr))
|
if (IsA(node, MinMaxExpr))
|
||||||
return true;
|
return true;
|
||||||
|
if (IsA(node, XmlExpr))
|
||||||
|
return true;
|
||||||
if (IsA(node, NullIfExpr))
|
if (IsA(node, NullIfExpr))
|
||||||
return true;
|
return true;
|
||||||
if (IsA(node, NullTest))
|
if (IsA(node, NullTest))
|
||||||
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);
|
||||||
}
|
}
|
||||||
@ -3328,22 +3328,23 @@ expression_tree_walker(Node *node,
|
|||||||
return walker(((CoalesceExpr *) node)->args, context);
|
return walker(((CoalesceExpr *) node)->args, context);
|
||||||
case T_MinMaxExpr:
|
case T_MinMaxExpr:
|
||||||
return walker(((MinMaxExpr *) node)->args, context);
|
return walker(((MinMaxExpr *) node)->args, context);
|
||||||
case T_NullIfExpr:
|
|
||||||
return walker(((NullIfExpr *) node)->args, context);
|
|
||||||
case T_NullTest:
|
|
||||||
return walker(((NullTest *) node)->arg, context);
|
|
||||||
case T_BooleanTest:
|
|
||||||
return walker(((BooleanTest *) node)->arg, context);
|
|
||||||
case T_XmlExpr:
|
case T_XmlExpr:
|
||||||
{
|
{
|
||||||
XmlExpr *xexpr = (XmlExpr *) node;
|
XmlExpr *xexpr = (XmlExpr *) node;
|
||||||
|
|
||||||
if (walker(xexpr->named_args, context))
|
if (walker(xexpr->named_args, context))
|
||||||
return true;
|
return true;
|
||||||
|
/* we assume walker doesn't care about arg_names */
|
||||||
if (walker(xexpr->args, context))
|
if (walker(xexpr->args, context))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case T_NullIfExpr:
|
||||||
|
return walker(((NullIfExpr *) node)->args, context);
|
||||||
|
case T_NullTest:
|
||||||
|
return walker(((NullTest *) node)->arg, context);
|
||||||
|
case T_BooleanTest:
|
||||||
|
return walker(((BooleanTest *) node)->arg, context);
|
||||||
case T_CoerceToDomain:
|
case T_CoerceToDomain:
|
||||||
return walker(((CoerceToDomain *) node)->arg, context);
|
return walker(((CoerceToDomain *) node)->arg, context);
|
||||||
case T_TargetEntry:
|
case T_TargetEntry:
|
||||||
@ -3874,6 +3875,7 @@ expression_tree_mutator(Node *node,
|
|||||||
|
|
||||||
FLATCOPY(newnode, xexpr, XmlExpr);
|
FLATCOPY(newnode, xexpr, XmlExpr);
|
||||||
MUTATE(newnode->named_args, xexpr->named_args, List *);
|
MUTATE(newnode->named_args, xexpr->named_args, List *);
|
||||||
|
/* assume mutator does not care about arg_names */
|
||||||
MUTATE(newnode->args, xexpr->args, List *);
|
MUTATE(newnode->args, xexpr->args, List *);
|
||||||
return (Node *) newnode;
|
return (Node *) newnode;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.569 2006/12/21 16:05:14 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.570 2006/12/24 00:29:18 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -348,8 +348,8 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
|
|
||||||
%type <target> xml_attribute_el
|
%type <target> xml_attribute_el
|
||||||
%type <list> xml_attribute_list xml_attributes
|
%type <list> xml_attribute_list xml_attributes
|
||||||
%type <node> xml_root_version
|
%type <node> xml_root_version opt_xml_root_standalone
|
||||||
%type <ival> opt_xml_root_standalone document_or_content xml_whitespace_option
|
%type <boolean> document_or_content xml_whitespace_option
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -371,13 +371,13 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
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
|
||||||
CONTENT CONVERSION_P CONVERT COPY CREATE CREATEDB
|
CONTENT_P 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 DOCUMENT DOMAIN_P DOUBLE_P DROP
|
DESC DISABLE_P DISTINCT DO DOCUMENT_P 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
|
||||||
@ -404,7 +404,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
|
|
||||||
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
|
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
|
||||||
|
|
||||||
NAME NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
|
NAME_P 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
|
||||||
|
|
||||||
@ -423,9 +423,9 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
|
|
||||||
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 STANDALONE START STATEMENT
|
SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
|
||||||
STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP SUBSTRING SUPERUSER_P SYMMETRIC
|
STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
|
||||||
SYSID SYSTEM_P
|
SYMMETRIC SYSID SYSTEM_P
|
||||||
|
|
||||||
TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP
|
TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP
|
||||||
TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
|
TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
|
||||||
@ -434,15 +434,15 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
|
UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
|
||||||
UPDATE USER USING
|
UPDATE USER USING
|
||||||
|
|
||||||
VACUUM VALID VALIDATOR VALUE VALUES VARCHAR VARYING
|
VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARYING
|
||||||
VERBOSE VERSION VIEW VOLATILE
|
VERBOSE VERSION_P VIEW VOLATILE
|
||||||
|
|
||||||
WHEN WHERE WHITESPACE WITH WITHOUT WORK WRITE
|
WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE
|
||||||
|
|
||||||
XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
|
XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
|
||||||
XMLPI XMLROOT XMLSERIALIZE
|
XMLPI XMLROOT XMLSERIALIZE
|
||||||
|
|
||||||
YEAR_P YES
|
YEAR_P YES_P
|
||||||
|
|
||||||
ZONE
|
ZONE
|
||||||
|
|
||||||
@ -493,7 +493,8 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
* 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
|
/* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */
|
||||||
|
%right PRESERVE STRIP_P
|
||||||
%%
|
%%
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -7880,95 +7881,54 @@ func_expr: func_name '(' ')'
|
|||||||
}
|
}
|
||||||
| XMLCONCAT '(' expr_list ')'
|
| XMLCONCAT '(' expr_list ')'
|
||||||
{
|
{
|
||||||
$$ = makeXmlExpr(IS_XMLCONCAT, NULL, NULL, $3);
|
$$ = makeXmlExpr(IS_XMLCONCAT, NULL, NIL, $3);
|
||||||
}
|
}
|
||||||
| XMLELEMENT '(' NAME ColLabel ')'
|
| XMLELEMENT '(' NAME_P ColLabel ')'
|
||||||
{
|
{
|
||||||
$$ = makeXmlExpr(IS_XMLELEMENT, $4, NULL, NULL);
|
$$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, NIL);
|
||||||
}
|
}
|
||||||
| XMLELEMENT '(' NAME ColLabel ',' xml_attributes ')'
|
| XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'
|
||||||
{
|
{
|
||||||
$$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, NULL);
|
$$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, NIL);
|
||||||
}
|
}
|
||||||
| XMLELEMENT '(' NAME ColLabel ',' expr_list ')'
|
| XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'
|
||||||
{
|
{
|
||||||
$$ = makeXmlExpr(IS_XMLELEMENT, $4, NULL, $6);
|
$$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, $6);
|
||||||
}
|
}
|
||||||
| XMLELEMENT '(' NAME ColLabel ',' xml_attributes ',' expr_list ')'
|
| XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'
|
||||||
{
|
{
|
||||||
$$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, $8);
|
$$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, $8);
|
||||||
}
|
}
|
||||||
| XMLFOREST '(' xml_attribute_list ')'
|
| XMLFOREST '(' xml_attribute_list ')'
|
||||||
{
|
{
|
||||||
$$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NULL);
|
$$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL);
|
||||||
}
|
}
|
||||||
| XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
|
| XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
|
||||||
{
|
{
|
||||||
FuncCall *n = makeNode(FuncCall);
|
$$ = makeXmlExpr(IS_XMLPARSE, NULL, NIL,
|
||||||
n->funcname = SystemFuncName("xmlparse");
|
list_make3($4,
|
||||||
n->args = list_make3(makeBoolAConst($3 == DOCUMENT), $4, makeBoolAConst($5 == PRESERVE));
|
makeBoolAConst($3),
|
||||||
n->agg_star = FALSE;
|
makeBoolAConst($5)));
|
||||||
n->agg_distinct = FALSE;
|
|
||||||
n->location = @1;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
}
|
||||||
| XMLPI '(' NAME ColLabel ')'
|
| XMLPI '(' NAME_P ColLabel ')'
|
||||||
{
|
{
|
||||||
FuncCall *n = makeNode(FuncCall);
|
$$ = makeXmlExpr(IS_XMLPI, $4, NULL, NIL);
|
||||||
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 ')'
|
| XMLPI '(' NAME_P ColLabel ',' a_expr ')'
|
||||||
{
|
{
|
||||||
FuncCall *n = makeNode(FuncCall);
|
$$ = makeXmlExpr(IS_XMLPI, $4, NULL, list_make1($6));
|
||||||
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 ')'
|
| XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')'
|
||||||
{
|
{
|
||||||
FuncCall *n = makeNode(FuncCall);
|
$$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
|
||||||
Node *ver;
|
list_make3($3, $5, $6));
|
||||||
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 ')'
|
| XMLSERIALIZE '(' document_or_content a_expr AS Typename ')'
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* FIXME: This should be made distinguishable from
|
* FIXME: This should be made distinguishable from
|
||||||
* CAST (for reverse compilation at least).
|
* CAST (for reverse compilation at least). Also,
|
||||||
|
* what about the document/content option??
|
||||||
*/
|
*/
|
||||||
$$ = makeTypeCast($4, $6);
|
$$ = makeTypeCast($4, $6);
|
||||||
}
|
}
|
||||||
@ -7977,14 +7937,32 @@ func_expr: func_name '(' ')'
|
|||||||
/*
|
/*
|
||||||
* SQL/XML support
|
* SQL/XML support
|
||||||
*/
|
*/
|
||||||
xml_root_version: VERSION a_expr { $$ = $2; }
|
xml_root_version: VERSION_P a_expr
|
||||||
| VERSION NO VALUE { $$ = NULL; }
|
{ $$ = $2; }
|
||||||
|
| VERSION_P NO VALUE_P
|
||||||
|
{
|
||||||
|
A_Const *val = makeNode(A_Const);
|
||||||
|
val->val.type = T_Null;
|
||||||
|
$$ = (Node *) val;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_xml_root_standalone: ',' STANDALONE YES { $$ = 1; }
|
opt_xml_root_standalone: ',' STANDALONE_P YES_P
|
||||||
| ',' STANDALONE NO { $$ = -1; }
|
{ $$ = (Node *) makeBoolAConst(true); }
|
||||||
| ',' STANDALONE NO VALUE { $$ = 0; }
|
| ',' STANDALONE_P NO
|
||||||
| /*EMPTY*/ { $$ = 0; }
|
{ $$ = (Node *) makeBoolAConst(false); }
|
||||||
|
| ',' STANDALONE_P NO VALUE_P
|
||||||
|
{
|
||||||
|
A_Const *val = makeNode(A_Const);
|
||||||
|
val->val.type = T_Null;
|
||||||
|
$$ = (Node *) val;
|
||||||
|
}
|
||||||
|
| /*EMPTY*/
|
||||||
|
{
|
||||||
|
A_Const *val = makeNode(A_Const);
|
||||||
|
val->val.type = T_Null;
|
||||||
|
$$ = (Node *) val;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
|
xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
|
||||||
@ -8000,7 +7978,7 @@ xml_attribute_el: a_expr AS ColLabel
|
|||||||
$$->name = $3;
|
$$->name = $3;
|
||||||
$$->indirection = NULL;
|
$$->indirection = NULL;
|
||||||
$$->val = (Node *) $1;
|
$$->val = (Node *) $1;
|
||||||
|
$$->location = @1;
|
||||||
}
|
}
|
||||||
| a_expr
|
| a_expr
|
||||||
{
|
{
|
||||||
@ -8008,16 +7986,21 @@ xml_attribute_el: a_expr AS ColLabel
|
|||||||
$$->name = NULL;
|
$$->name = NULL;
|
||||||
$$->indirection = NULL;
|
$$->indirection = NULL;
|
||||||
$$->val = (Node *) $1;
|
$$->val = (Node *) $1;
|
||||||
|
$$->location = @1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
document_or_content: DOCUMENT { $$ = DOCUMENT; }
|
document_or_content: DOCUMENT_P { $$ = TRUE; }
|
||||||
| CONTENT { $$ = CONTENT; }
|
| CONTENT_P { $$ = FALSE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
xml_whitespace_option: PRESERVE WHITESPACE { $$ = PRESERVE; }
|
/*
|
||||||
| STRIP WHITESPACE { $$ = STRIP; }
|
* XXX per SQL spec, the default should be STRIP WHITESPACE, but since we
|
||||||
| /*EMPTY*/ { $$ = STRIP; }
|
* haven't implemented that yet, temporarily default to PRESERVE.
|
||||||
|
*/
|
||||||
|
xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = TRUE; }
|
||||||
|
| STRIP_P WHITESPACE_P { $$ = FALSE; }
|
||||||
|
| /*EMPTY*/ { $$ = TRUE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -8712,7 +8695,7 @@ unreserved_keyword:
|
|||||||
| CONCURRENTLY
|
| CONCURRENTLY
|
||||||
| CONNECTION
|
| CONNECTION
|
||||||
| CONSTRAINTS
|
| CONSTRAINTS
|
||||||
| CONTENT
|
| CONTENT_P
|
||||||
| CONVERSION_P
|
| CONVERSION_P
|
||||||
| COPY
|
| COPY
|
||||||
| CREATEDB
|
| CREATEDB
|
||||||
@ -8732,7 +8715,7 @@ unreserved_keyword:
|
|||||||
| DELIMITER
|
| DELIMITER
|
||||||
| DELIMITERS
|
| DELIMITERS
|
||||||
| DISABLE_P
|
| DISABLE_P
|
||||||
| DOCUMENT
|
| DOCUMENT_P
|
||||||
| DOMAIN_P
|
| DOMAIN_P
|
||||||
| DOUBLE_P
|
| DOUBLE_P
|
||||||
| DROP
|
| DROP
|
||||||
@ -8792,7 +8775,7 @@ unreserved_keyword:
|
|||||||
| MODE
|
| MODE
|
||||||
| MONTH_P
|
| MONTH_P
|
||||||
| MOVE
|
| MOVE
|
||||||
| NAME
|
| NAME_P
|
||||||
| NAMES
|
| NAMES
|
||||||
| NEXT
|
| NEXT
|
||||||
| NO
|
| NO
|
||||||
@ -8853,18 +8836,18 @@ unreserved_keyword:
|
|||||||
| SHOW
|
| SHOW
|
||||||
| SIMPLE
|
| SIMPLE
|
||||||
| STABLE
|
| STABLE
|
||||||
| STANDALONE
|
| STANDALONE_P
|
||||||
| START
|
| START
|
||||||
| STATEMENT
|
| STATEMENT
|
||||||
| STATISTICS
|
| STATISTICS
|
||||||
| STDIN
|
| STDIN
|
||||||
| STDOUT
|
| STDOUT
|
||||||
| STORAGE
|
| STORAGE
|
||||||
| STRIP
|
| STRICT_P
|
||||||
|
| STRIP_P
|
||||||
| SUPERUSER_P
|
| SUPERUSER_P
|
||||||
| SYSID
|
| SYSID
|
||||||
| SYSTEM_P
|
| SYSTEM_P
|
||||||
| STRICT_P
|
|
||||||
| TABLESPACE
|
| TABLESPACE
|
||||||
| TEMP
|
| TEMP
|
||||||
| TEMPLATE
|
| TEMPLATE
|
||||||
@ -8883,18 +8866,18 @@ unreserved_keyword:
|
|||||||
| VACUUM
|
| VACUUM
|
||||||
| VALID
|
| VALID
|
||||||
| VALIDATOR
|
| VALIDATOR
|
||||||
|
| VALUE_P
|
||||||
| VARYING
|
| VARYING
|
||||||
| VERSION
|
| VERSION_P
|
||||||
| VIEW
|
| VIEW
|
||||||
| VALUE
|
|
||||||
| VOLATILE
|
| VOLATILE
|
||||||
| WHITESPACE
|
| WHITESPACE_P
|
||||||
| WITH
|
| WITH
|
||||||
| WITHOUT
|
| WITHOUT
|
||||||
| WORK
|
| WORK
|
||||||
| WRITE
|
| WRITE
|
||||||
| YEAR_P
|
| YEAR_P
|
||||||
| YES
|
| YES_P
|
||||||
| ZONE
|
| ZONE
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -8948,8 +8931,8 @@ col_name_keyword:
|
|||||||
| VALUES
|
| VALUES
|
||||||
| VARCHAR
|
| VARCHAR
|
||||||
| XMLATTRIBUTES
|
| XMLATTRIBUTES
|
||||||
| XMLELEMENT
|
|
||||||
| XMLCONCAT
|
| XMLCONCAT
|
||||||
|
| XMLELEMENT
|
||||||
| XMLFOREST
|
| XMLFOREST
|
||||||
| XMLPARSE
|
| XMLPARSE
|
||||||
| XMLPI
|
| XMLPI
|
||||||
@ -9493,9 +9476,15 @@ static Node *
|
|||||||
makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
||||||
{
|
{
|
||||||
XmlExpr *x = makeNode(XmlExpr);
|
XmlExpr *x = makeNode(XmlExpr);
|
||||||
|
|
||||||
x->op = op;
|
x->op = op;
|
||||||
x->name = name;
|
x->name = name;
|
||||||
|
/*
|
||||||
|
* named_args is a list of ResTarget; it'll be split apart into separate
|
||||||
|
* expression and name lists in transformXmlExpr().
|
||||||
|
*/
|
||||||
x->named_args = named_args;
|
x->named_args = named_args;
|
||||||
|
x->arg_names = NIL;
|
||||||
x->args = args;
|
x->args = args;
|
||||||
return (Node *) x;
|
return (Node *) x;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.178 2006/12/21 16:05:14 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.179 2006/12/24 00:29:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -89,7 +89,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"connection", CONNECTION},
|
{"connection", CONNECTION},
|
||||||
{"constraint", CONSTRAINT},
|
{"constraint", CONSTRAINT},
|
||||||
{"constraints", CONSTRAINTS},
|
{"constraints", CONSTRAINTS},
|
||||||
{"content", CONTENT},
|
{"content", CONTENT_P},
|
||||||
{"conversion", CONVERSION_P},
|
{"conversion", CONVERSION_P},
|
||||||
{"convert", CONVERT},
|
{"convert", CONVERT},
|
||||||
{"copy", COPY},
|
{"copy", COPY},
|
||||||
@ -124,7 +124,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"disable", DISABLE_P},
|
{"disable", DISABLE_P},
|
||||||
{"distinct", DISTINCT},
|
{"distinct", DISTINCT},
|
||||||
{"do", DO},
|
{"do", DO},
|
||||||
{"document", DOCUMENT},
|
{"document", DOCUMENT_P},
|
||||||
{"domain", DOMAIN_P},
|
{"domain", DOMAIN_P},
|
||||||
{"double", DOUBLE_P},
|
{"double", DOUBLE_P},
|
||||||
{"drop", DROP},
|
{"drop", DROP},
|
||||||
@ -220,7 +220,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"mode", MODE},
|
{"mode", MODE},
|
||||||
{"month", MONTH_P},
|
{"month", MONTH_P},
|
||||||
{"move", MOVE},
|
{"move", MOVE},
|
||||||
{"name", NAME},
|
{"name", NAME_P},
|
||||||
{"names", NAMES},
|
{"names", NAMES},
|
||||||
{"national", NATIONAL},
|
{"national", NATIONAL},
|
||||||
{"natural", NATURAL},
|
{"natural", NATURAL},
|
||||||
@ -317,7 +317,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"smallint", SMALLINT},
|
{"smallint", SMALLINT},
|
||||||
{"some", SOME},
|
{"some", SOME},
|
||||||
{"stable", STABLE},
|
{"stable", STABLE},
|
||||||
{"standalone", STANDALONE},
|
{"standalone", STANDALONE_P},
|
||||||
{"start", START},
|
{"start", START},
|
||||||
{"statement", STATEMENT},
|
{"statement", STATEMENT},
|
||||||
{"statistics", STATISTICS},
|
{"statistics", STATISTICS},
|
||||||
@ -325,7 +325,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"stdout", STDOUT},
|
{"stdout", STDOUT},
|
||||||
{"storage", STORAGE},
|
{"storage", STORAGE},
|
||||||
{"strict", STRICT_P},
|
{"strict", STRICT_P},
|
||||||
{"strip", STRIP},
|
{"strip", STRIP_P},
|
||||||
{"substring", SUBSTRING},
|
{"substring", SUBSTRING},
|
||||||
{"superuser", SUPERUSER_P},
|
{"superuser", SUPERUSER_P},
|
||||||
{"symmetric", SYMMETRIC},
|
{"symmetric", SYMMETRIC},
|
||||||
@ -362,17 +362,17 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"vacuum", VACUUM},
|
{"vacuum", VACUUM},
|
||||||
{"valid", VALID},
|
{"valid", VALID},
|
||||||
{"validator", VALIDATOR},
|
{"validator", VALIDATOR},
|
||||||
{"value", VALUE},
|
{"value", VALUE_P},
|
||||||
{"values", VALUES},
|
{"values", VALUES},
|
||||||
{"varchar", VARCHAR},
|
{"varchar", VARCHAR},
|
||||||
{"varying", VARYING},
|
{"varying", VARYING},
|
||||||
{"verbose", VERBOSE},
|
{"verbose", VERBOSE},
|
||||||
{"version", VERSION},
|
{"version", VERSION_P},
|
||||||
{"view", VIEW},
|
{"view", VIEW},
|
||||||
{"volatile", VOLATILE},
|
{"volatile", VOLATILE},
|
||||||
{"when", WHEN},
|
{"when", WHEN},
|
||||||
{"where", WHERE},
|
{"where", WHERE},
|
||||||
{"whitespace", WHITESPACE},
|
{"whitespace", WHITESPACE_P},
|
||||||
{"with", WITH},
|
{"with", WITH},
|
||||||
{"without", WITHOUT},
|
{"without", WITHOUT},
|
||||||
{"work", WORK},
|
{"work", WORK},
|
||||||
@ -386,7 +386,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"xmlroot", XMLROOT},
|
{"xmlroot", XMLROOT},
|
||||||
{"xmlserialize", XMLSERIALIZE},
|
{"xmlserialize", XMLSERIALIZE},
|
||||||
{"year", YEAR_P},
|
{"year", YEAR_P},
|
||||||
{"yes", YES},
|
{"yes", YES_P},
|
||||||
{"zone", ZONE},
|
{"zone", ZONE},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.159 2006/11/28 12:54:41 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.160 2006/12/24 00:29:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1094,7 +1094,7 @@ transformLimitClause(ParseState *pstate, Node *clause,
|
|||||||
|
|
||||||
qual = transformExpr(pstate, clause);
|
qual = transformExpr(pstate, clause);
|
||||||
|
|
||||||
qual = coerce_to_bigint(pstate, qual, constructName);
|
qual = coerce_to_specific_type(pstate, qual, INT8OID, constructName);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LIMIT can't refer to any vars or aggregates of the current query; we
|
* LIMIT can't refer to any vars or aggregates of the current query; we
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.148 2006/12/21 16:05:14 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.149 2006/12/24 00:29:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -840,8 +840,8 @@ coerce_to_boolean(ParseState *pstate, Node *node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* coerce_to_integer()
|
* coerce_to_specific_type()
|
||||||
* Coerce an argument of a construct that requires integer input.
|
* Coerce an argument of a construct that requires a specific data type.
|
||||||
* Also check that input is not a set.
|
* Also check that input is not a set.
|
||||||
*
|
*
|
||||||
* Returns the possibly-transformed node tree.
|
* Returns the possibly-transformed node tree.
|
||||||
@ -850,103 +850,26 @@ coerce_to_boolean(ParseState *pstate, Node *node,
|
|||||||
* processing is wanted.
|
* processing is wanted.
|
||||||
*/
|
*/
|
||||||
Node *
|
Node *
|
||||||
coerce_to_integer(ParseState *pstate, Node *node,
|
coerce_to_specific_type(ParseState *pstate, Node *node,
|
||||||
|
Oid targetTypeId,
|
||||||
const char *constructName)
|
const char *constructName)
|
||||||
{
|
{
|
||||||
Oid inputTypeId = exprType(node);
|
Oid inputTypeId = exprType(node);
|
||||||
|
|
||||||
if (inputTypeId != INT4OID)
|
if (inputTypeId != targetTypeId)
|
||||||
{
|
{
|
||||||
node = coerce_to_target_type(pstate, node, inputTypeId,
|
node = coerce_to_target_type(pstate, node, inputTypeId,
|
||||||
INT4OID, -1,
|
targetTypeId, -1,
|
||||||
COERCION_ASSIGNMENT,
|
COERCION_ASSIGNMENT,
|
||||||
COERCE_IMPLICIT_CAST);
|
COERCE_IMPLICIT_CAST);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||||
/* translator: first %s is name of a SQL construct, eg LIMIT */
|
/* translator: first %s is name of a SQL construct, eg LIMIT */
|
||||||
errmsg("argument of %s must be type integer, not type %s",
|
errmsg("argument of %s must be type %s, not type %s",
|
||||||
constructName, format_type_be(inputTypeId))));
|
constructName,
|
||||||
}
|
format_type_be(targetTypeId),
|
||||||
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* coerce_to_bigint()
|
|
||||||
* Coerce an argument of a construct that requires int8 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_bigint(ParseState *pstate, Node *node,
|
|
||||||
const char *constructName)
|
|
||||||
{
|
|
||||||
Oid inputTypeId = exprType(node);
|
|
||||||
|
|
||||||
if (inputTypeId != INT8OID)
|
|
||||||
{
|
|
||||||
node = coerce_to_target_type(pstate, node, inputTypeId,
|
|
||||||
INT8OID, -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 bigint, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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))
|
if (expression_returns_set(node))
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.201 2006/12/23 00:43:11 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.202 2006/12/24 00:29:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -220,6 +220,10 @@ transformExpr(ParseState *pstate, Node *expr)
|
|||||||
result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
|
result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_XmlExpr:
|
||||||
|
result = transformXmlExpr(pstate, (XmlExpr *) expr);
|
||||||
|
break;
|
||||||
|
|
||||||
case T_NullTest:
|
case T_NullTest:
|
||||||
{
|
{
|
||||||
NullTest *n = (NullTest *) expr;
|
NullTest *n = (NullTest *) expr;
|
||||||
@ -234,10 +238,6 @@ 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.
|
||||||
@ -1375,6 +1375,107 @@ transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m)
|
|||||||
return (Node *) newm;
|
return (Node *) newm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Node *
|
||||||
|
transformXmlExpr(ParseState *pstate, XmlExpr *x)
|
||||||
|
{
|
||||||
|
XmlExpr *newx = makeNode(XmlExpr);
|
||||||
|
ListCell *lc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
newx->op = x->op;
|
||||||
|
if (x->name)
|
||||||
|
newx->name = map_sql_identifier_to_xml_name(x->name, false);
|
||||||
|
else
|
||||||
|
newx->name = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gram.y built the named args as a list of ResTarget. Transform each,
|
||||||
|
* and break the names out as a separate list.
|
||||||
|
*/
|
||||||
|
newx->named_args = NIL;
|
||||||
|
newx->arg_names = NIL;
|
||||||
|
|
||||||
|
foreach(lc, x->named_args)
|
||||||
|
{
|
||||||
|
ResTarget *r = (ResTarget *) lfirst(lc);
|
||||||
|
Node *expr;
|
||||||
|
char *argname;
|
||||||
|
|
||||||
|
Assert(IsA(r, ResTarget));
|
||||||
|
|
||||||
|
expr = transformExpr(pstate, r->val);
|
||||||
|
|
||||||
|
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")));
|
||||||
|
argname = NULL; /* keep compiler quiet */
|
||||||
|
}
|
||||||
|
|
||||||
|
newx->named_args = lappend(newx->named_args, expr);
|
||||||
|
newx->arg_names = lappend(newx->arg_names, makeString(argname));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The other arguments are of varying types depending on the function */
|
||||||
|
newx->args = NIL;
|
||||||
|
i = 0;
|
||||||
|
foreach(lc, x->args)
|
||||||
|
{
|
||||||
|
Node *e = (Node *) lfirst(lc);
|
||||||
|
Node *newe;
|
||||||
|
|
||||||
|
newe = transformExpr(pstate, e);
|
||||||
|
switch (x->op)
|
||||||
|
{
|
||||||
|
case IS_XMLCONCAT:
|
||||||
|
newe = coerce_to_specific_type(pstate, newe, XMLOID,
|
||||||
|
"XMLCONCAT");
|
||||||
|
break;
|
||||||
|
case IS_XMLELEMENT:
|
||||||
|
newe = coerce_to_specific_type(pstate, newe, XMLOID,
|
||||||
|
"XMLELEMENT");
|
||||||
|
break;
|
||||||
|
case IS_XMLFOREST:
|
||||||
|
newe = coerce_to_specific_type(pstate, newe, XMLOID,
|
||||||
|
"XMLFOREST");
|
||||||
|
break;
|
||||||
|
case IS_XMLPARSE:
|
||||||
|
if (i == 0)
|
||||||
|
newe = coerce_to_specific_type(pstate, newe, TEXTOID,
|
||||||
|
"XMLPARSE");
|
||||||
|
else
|
||||||
|
newe = coerce_to_boolean(pstate, newe, "XMLPARSE");
|
||||||
|
break;
|
||||||
|
case IS_XMLPI:
|
||||||
|
newe = coerce_to_specific_type(pstate, newe, TEXTOID,
|
||||||
|
"XMLPI");
|
||||||
|
break;
|
||||||
|
case IS_XMLROOT:
|
||||||
|
if (i == 0)
|
||||||
|
newe = coerce_to_specific_type(pstate, newe, XMLOID,
|
||||||
|
"XMLROOT");
|
||||||
|
else if (i == 1)
|
||||||
|
newe = coerce_to_specific_type(pstate, newe, TEXTOID,
|
||||||
|
"XMLROOT");
|
||||||
|
else
|
||||||
|
newe = coerce_to_boolean(pstate, newe, "XMLROOT");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
newx->args = lappend(newx->args, newe);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Node *) newx;
|
||||||
|
}
|
||||||
|
|
||||||
static Node *
|
static Node *
|
||||||
transformBooleanTest(ParseState *pstate, BooleanTest *b)
|
transformBooleanTest(ParseState *pstate, BooleanTest *b)
|
||||||
{
|
{
|
||||||
@ -1415,56 +1516,6 @@ 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.*".
|
||||||
*
|
*
|
||||||
@ -1715,6 +1766,9 @@ exprType(Node *expr)
|
|||||||
case T_MinMaxExpr:
|
case T_MinMaxExpr:
|
||||||
type = ((MinMaxExpr *) expr)->minmaxtype;
|
type = ((MinMaxExpr *) expr)->minmaxtype;
|
||||||
break;
|
break;
|
||||||
|
case T_XmlExpr:
|
||||||
|
type = XMLOID;
|
||||||
|
break;
|
||||||
case T_NullIfExpr:
|
case T_NullIfExpr:
|
||||||
type = exprType((Node *) linitial(((NullIfExpr *) expr)->args));
|
type = exprType((Node *) linitial(((NullIfExpr *) expr)->args));
|
||||||
break;
|
break;
|
||||||
@ -1724,9 +1778,6 @@ 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.150 2006/12/21 16:05:14 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.151 2006/12/24 00:29:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1328,6 +1328,15 @@ FigureColnameInternal(Node *node, char **name)
|
|||||||
case IS_XMLFOREST:
|
case IS_XMLFOREST:
|
||||||
*name = "xmlforest";
|
*name = "xmlforest";
|
||||||
return 2;
|
return 2;
|
||||||
|
case IS_XMLPARSE:
|
||||||
|
*name = "xmlparse";
|
||||||
|
return 2;
|
||||||
|
case IS_XMLPI:
|
||||||
|
*name = "xmlpi";
|
||||||
|
return 2;
|
||||||
|
case IS_XMLROOT:
|
||||||
|
*name = "xmlroot";
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -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.237 2006/12/23 00:43:11 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.238 2006/12/24 00:29:19 tgl Exp $
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -2988,8 +2988,8 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
|||||||
case T_RowExpr:
|
case T_RowExpr:
|
||||||
case T_CoalesceExpr:
|
case T_CoalesceExpr:
|
||||||
case T_MinMaxExpr:
|
case T_MinMaxExpr:
|
||||||
case T_NullIfExpr:
|
|
||||||
case T_XmlExpr:
|
case T_XmlExpr:
|
||||||
|
case T_NullIfExpr:
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
case T_FuncExpr:
|
case T_FuncExpr:
|
||||||
/* function-like: name(..) or name[..] */
|
/* function-like: name(..) or name[..] */
|
||||||
@ -3097,8 +3097,8 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
|||||||
case T_RowExpr: /* other separators */
|
case T_RowExpr: /* other separators */
|
||||||
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_XmlExpr: /* own parentheses */
|
case T_XmlExpr: /* own parentheses */
|
||||||
|
case T_NullIfExpr: /* other separators */
|
||||||
case T_Aggref: /* own parentheses */
|
case T_Aggref: /* own parentheses */
|
||||||
case T_CaseExpr: /* other separators */
|
case T_CaseExpr: /* other separators */
|
||||||
return true;
|
return true;
|
||||||
@ -3146,8 +3146,8 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
|||||||
case T_RowExpr: /* other separators */
|
case T_RowExpr: /* other separators */
|
||||||
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_XmlExpr: /* own parentheses */
|
case T_XmlExpr: /* own parentheses */
|
||||||
|
case T_NullIfExpr: /* other separators */
|
||||||
case T_Aggref: /* own parentheses */
|
case T_Aggref: /* own parentheses */
|
||||||
case T_CaseExpr: /* other separators */
|
case T_CaseExpr: /* other separators */
|
||||||
return true;
|
return true;
|
||||||
@ -3779,6 +3779,140 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_XmlExpr:
|
||||||
|
{
|
||||||
|
XmlExpr *xexpr = (XmlExpr *) node;
|
||||||
|
bool needcomma = false;
|
||||||
|
ListCell *arg;
|
||||||
|
ListCell *narg;
|
||||||
|
Const *con;
|
||||||
|
|
||||||
|
switch (xexpr->op)
|
||||||
|
{
|
||||||
|
case IS_XMLCONCAT:
|
||||||
|
appendStringInfoString(buf, "XMLCONCAT(");
|
||||||
|
break;
|
||||||
|
case IS_XMLELEMENT:
|
||||||
|
appendStringInfoString(buf, "XMLELEMENT(");
|
||||||
|
break;
|
||||||
|
case IS_XMLFOREST:
|
||||||
|
appendStringInfoString(buf, "XMLFOREST(");
|
||||||
|
break;
|
||||||
|
case IS_XMLPARSE:
|
||||||
|
appendStringInfoString(buf, "XMLPARSE(");
|
||||||
|
break;
|
||||||
|
case IS_XMLPI:
|
||||||
|
appendStringInfoString(buf, "XMLPI(");
|
||||||
|
break;
|
||||||
|
case IS_XMLROOT:
|
||||||
|
appendStringInfoString(buf, "XMLROOT(");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (xexpr->name)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* XXX need to de-escape the name
|
||||||
|
*/
|
||||||
|
appendStringInfo(buf, "NAME %s",
|
||||||
|
quote_identifier(xexpr->name));
|
||||||
|
needcomma = true;
|
||||||
|
}
|
||||||
|
if (xexpr->named_args)
|
||||||
|
{
|
||||||
|
if (xexpr->op != IS_XMLFOREST)
|
||||||
|
{
|
||||||
|
if (needcomma)
|
||||||
|
appendStringInfoString(buf, ", ");
|
||||||
|
appendStringInfoString(buf, "XMLATTRIBUTES(");
|
||||||
|
needcomma = false;
|
||||||
|
}
|
||||||
|
forboth(arg, xexpr->named_args, narg, xexpr->arg_names)
|
||||||
|
{
|
||||||
|
Node *e = (Node *) lfirst(arg);
|
||||||
|
char *argname = strVal(lfirst(narg));
|
||||||
|
|
||||||
|
if (needcomma)
|
||||||
|
appendStringInfoString(buf, ", ");
|
||||||
|
get_rule_expr((Node *) e, context, true);
|
||||||
|
/*
|
||||||
|
* XXX need to de-escape the name
|
||||||
|
*/
|
||||||
|
appendStringInfo(buf, " AS %s",
|
||||||
|
quote_identifier(argname));
|
||||||
|
needcomma = true;
|
||||||
|
}
|
||||||
|
if (xexpr->op != IS_XMLFOREST)
|
||||||
|
appendStringInfoChar(buf, ')');
|
||||||
|
}
|
||||||
|
if (xexpr->args)
|
||||||
|
{
|
||||||
|
if (needcomma)
|
||||||
|
appendStringInfoString(buf, ", ");
|
||||||
|
switch (xexpr->op)
|
||||||
|
{
|
||||||
|
case IS_XMLCONCAT:
|
||||||
|
case IS_XMLELEMENT:
|
||||||
|
case IS_XMLFOREST:
|
||||||
|
case IS_XMLPI:
|
||||||
|
/* no extra decoration needed */
|
||||||
|
get_rule_expr((Node *) xexpr->args, context, true);
|
||||||
|
break;
|
||||||
|
case IS_XMLPARSE:
|
||||||
|
Assert(list_length(xexpr->args) == 3);
|
||||||
|
|
||||||
|
con = (Const *) lsecond(xexpr->args);
|
||||||
|
Assert(IsA(con, Const));
|
||||||
|
Assert(!con->constisnull);
|
||||||
|
if (DatumGetBool(con->constvalue))
|
||||||
|
appendStringInfoString(buf, "DOCUMENT ");
|
||||||
|
else
|
||||||
|
appendStringInfoString(buf, "CONTENT ");
|
||||||
|
|
||||||
|
get_rule_expr((Node *) linitial(xexpr->args),
|
||||||
|
context, true);
|
||||||
|
|
||||||
|
con = (Const *) lthird(xexpr->args);
|
||||||
|
Assert(IsA(con, Const));
|
||||||
|
Assert(!con->constisnull);
|
||||||
|
if (DatumGetBool(con->constvalue))
|
||||||
|
appendStringInfoString(buf,
|
||||||
|
" PRESERVE WHITESPACE");
|
||||||
|
else
|
||||||
|
appendStringInfoString(buf,
|
||||||
|
" STRIP WHITESPACE");
|
||||||
|
break;
|
||||||
|
case IS_XMLROOT:
|
||||||
|
Assert(list_length(xexpr->args) == 3);
|
||||||
|
|
||||||
|
get_rule_expr((Node *) linitial(xexpr->args),
|
||||||
|
context, true);
|
||||||
|
|
||||||
|
appendStringInfoString(buf, ", VERSION ");
|
||||||
|
con = (Const *) lsecond(xexpr->args);
|
||||||
|
if (IsA(con, Const) &&
|
||||||
|
con->constisnull)
|
||||||
|
appendStringInfoString(buf, "NO VALUE");
|
||||||
|
else
|
||||||
|
get_rule_expr((Node *) con, context, false);
|
||||||
|
|
||||||
|
con = (Const *) lthird(xexpr->args);
|
||||||
|
Assert(IsA(con, Const));
|
||||||
|
if (con->constisnull)
|
||||||
|
/* suppress STANDALONE NO VALUE */ ;
|
||||||
|
else if (DatumGetBool(con->constvalue))
|
||||||
|
appendStringInfoString(buf,
|
||||||
|
", STANDALONE YES");
|
||||||
|
else
|
||||||
|
appendStringInfoString(buf,
|
||||||
|
", STANDALONE NO");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
appendStringInfoChar(buf, ')');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case T_NullIfExpr:
|
case T_NullIfExpr:
|
||||||
{
|
{
|
||||||
NullIfExpr *nullifexpr = (NullIfExpr *) node;
|
NullIfExpr *nullifexpr = (NullIfExpr *) node;
|
||||||
@ -3849,28 +3983,6 @@ 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;
|
||||||
|
@ -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/backend/utils/adt/xml.c,v 1.2 2006/12/23 04:56:50 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.3 2006/12/24 00:29:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -41,15 +41,6 @@
|
|||||||
|
|
||||||
#ifdef USE_LIBXML
|
#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 PG_XML_DEFAULT_URI "dummy.xml"
|
||||||
#define XML_ERRBUF_SIZE 200
|
#define XML_ERRBUF_SIZE 200
|
||||||
|
|
||||||
@ -177,31 +168,18 @@ xmlcomment(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
xmlparse(PG_FUNCTION_ARGS)
|
texttoxml(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
text *data = PG_GETARG_TEXT_P(0);
|
||||||
|
|
||||||
|
PG_RETURN_XML_P(xmlparse(data, false, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmltype *
|
||||||
|
xmlparse(text *data, bool is_document, bool preserve_whitespace)
|
||||||
{
|
{
|
||||||
#ifdef USE_LIBXML
|
#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)
|
if (!preserve_whitespace)
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
@ -213,111 +191,93 @@ xmlparse(PG_FUNCTION_ARGS)
|
|||||||
* valies defined by internal DTD are applied'. As for external
|
* valies defined by internal DTD are applied'. As for external
|
||||||
* DTDs, we try to support them too, (see SQL/XML:10.16.7.e)
|
* 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 */
|
xml_parse(data, XML_PARSE_DTDATTR, is_document);
|
||||||
|
|
||||||
PG_RETURN_XML_P(data);
|
return (xmltype *) data;
|
||||||
#else
|
#else
|
||||||
NO_XML_SUPPORT();
|
NO_XML_SUPPORT();
|
||||||
return 0;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Datum
|
xmltype *
|
||||||
xmlpi(PG_FUNCTION_ARGS)
|
xmlpi(char *target, text *arg)
|
||||||
{
|
{
|
||||||
#ifdef USE_LIBXML
|
#ifdef USE_LIBXML
|
||||||
char *target = NameStr(*PG_GETARG_NAME(0));
|
xmltype *result;
|
||||||
StringInfoData buf;
|
StringInfoData buf;
|
||||||
|
|
||||||
if (strlen(target) >= 3
|
if (pg_strncasecmp(target, "xml", 3) == 0)
|
||||||
&& (target[0] == 'x' || target[0] == 'X')
|
|
||||||
&& (target[1] == 'm' || target[1] == 'M')
|
|
||||||
&& (target[2] == 'l' || target[2] == 'L'))
|
|
||||||
{
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
|
||||||
errmsg("invalid XML processing instruction"),
|
errmsg("invalid XML processing instruction"),
|
||||||
errdetail("XML processing instruction target name cannot start with \"xml\".")));
|
errdetail("XML processing instruction target name cannot start with \"xml\".")));
|
||||||
}
|
|
||||||
|
|
||||||
initStringInfo(&buf);
|
initStringInfo(&buf);
|
||||||
|
|
||||||
appendStringInfo(&buf, "<?");
|
appendStringInfo(&buf, "<?%s", target);
|
||||||
appendStringInfoString(&buf, map_sql_identifier_to_xml_name(target, false));
|
|
||||||
if (PG_NARGS() > 1)
|
if (arg != NULL)
|
||||||
{
|
{
|
||||||
text *arg = PG_GETARG_TEXT_P(1);
|
|
||||||
char *string;
|
char *string;
|
||||||
|
|
||||||
string = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(arg)));
|
string = DatumGetCString(DirectFunctionCall1(textout,
|
||||||
if (strstr(string, "?>"))
|
PointerGetDatum(arg)));
|
||||||
|
if (strstr(string, "?>") != NULL)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
|
(errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
|
||||||
errmsg("invalid XML processing instruction"),
|
errmsg("invalid XML processing instruction"),
|
||||||
errdetail("XML processing instruction cannot contain \"?>\".")));
|
errdetail("XML processing instruction cannot contain \"?>\".")));
|
||||||
|
|
||||||
appendStringInfoString(&buf, " ");
|
appendStringInfoChar(&buf, ' ');
|
||||||
appendStringInfoString(&buf, string);
|
appendStringInfoString(&buf, string);
|
||||||
|
pfree(string);
|
||||||
}
|
}
|
||||||
appendStringInfoString(&buf, "?>");
|
appendStringInfoString(&buf, "?>");
|
||||||
|
|
||||||
PG_RETURN_XML_P(stringinfo_to_xmltype(&buf));
|
result = stringinfo_to_xmltype(&buf);
|
||||||
|
pfree(buf.data);
|
||||||
|
return result;
|
||||||
#else
|
#else
|
||||||
NO_XML_SUPPORT();
|
NO_XML_SUPPORT();
|
||||||
return 0;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Datum
|
xmltype *
|
||||||
xmlroot(PG_FUNCTION_ARGS)
|
xmlroot(xmltype *data, text *version, int standalone)
|
||||||
{
|
{
|
||||||
#ifdef USE_LIBXML
|
#ifdef USE_LIBXML
|
||||||
xmltype *data;
|
xmltype *result;
|
||||||
text *version;
|
|
||||||
int standalone;
|
|
||||||
StringInfoData buf;
|
StringInfoData buf;
|
||||||
|
|
||||||
if (PG_ARGISNULL(0))
|
initStringInfo(&buf);
|
||||||
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
|
* FIXME: This is probably supposed to be cleverer if there
|
||||||
* already is an XML preamble.
|
* already is an XML preamble.
|
||||||
*/
|
*/
|
||||||
initStringInfo(&buf);
|
|
||||||
|
|
||||||
appendStringInfo(&buf,"<?xml");
|
appendStringInfo(&buf,"<?xml");
|
||||||
if (version) {
|
if (version)
|
||||||
|
{
|
||||||
appendStringInfo(&buf, " version=\"");
|
appendStringInfo(&buf, " version=\"");
|
||||||
appendStringInfoText(&buf, version);
|
appendStringInfoText(&buf, version);
|
||||||
appendStringInfo(&buf, "\"");
|
appendStringInfo(&buf, "\"");
|
||||||
}
|
}
|
||||||
if (standalone)
|
if (standalone)
|
||||||
appendStringInfo(&buf, " standalone=\"%s\"", (standalone == 1 ? "yes" : "no"));
|
appendStringInfo(&buf, " standalone=\"%s\"",
|
||||||
|
(standalone == 1 ? "yes" : "no"));
|
||||||
appendStringInfo(&buf, "?>");
|
appendStringInfo(&buf, "?>");
|
||||||
appendStringInfoText(&buf, (text *) data);
|
appendStringInfoText(&buf, (text *) data);
|
||||||
|
|
||||||
PG_RETURN_XML_P(stringinfo_to_xmltype(&buf));
|
result = stringinfo_to_xmltype(&buf);
|
||||||
|
pfree(buf.data);
|
||||||
|
return result;
|
||||||
#else
|
#else
|
||||||
NO_XML_SUPPORT();
|
NO_XML_SUPPORT();
|
||||||
return 0;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,7 +416,7 @@ xml_parse(text *data, int opts, bool is_document)
|
|||||||
|
|
||||||
/* first, we try to parse the string as XML doc, then, as XML chunk */
|
/* first, we try to parse the string as XML doc, then, as XML chunk */
|
||||||
ereport(DEBUG3, (errmsg("string to parse: %s", string)));
|
ereport(DEBUG3, (errmsg("string to parse: %s", string)));
|
||||||
if (len > 4 && CMP5(string, '<', '?', 'x', 'm', 'l'))
|
if (len >= 5 && strncmp((char *) string, "<?xml", 5) == 0)
|
||||||
{
|
{
|
||||||
/* consider it as DOCUMENT */
|
/* consider it as DOCUMENT */
|
||||||
doc = xmlCtxtReadMemory(ctxt, (char *) string, len,
|
doc = xmlCtxtReadMemory(ctxt, (char *) string, len,
|
||||||
@ -918,10 +878,8 @@ map_sql_identifier_to_xml_name(char *ident, bool fully_escaped)
|
|||||||
appendStringInfo(&buf, "_x003A_");
|
appendStringInfo(&buf, "_x003A_");
|
||||||
else if (*p == '_' && *(p+1) == 'x')
|
else if (*p == '_' && *(p+1) == 'x')
|
||||||
appendStringInfo(&buf, "_x005F_");
|
appendStringInfo(&buf, "_x005F_");
|
||||||
else if (fully_escaped && p == ident
|
else if (fully_escaped && p == ident &&
|
||||||
&& ( *p == 'x' || *p == 'X')
|
pg_strncasecmp(p, "xml", 3) == 0)
|
||||||
&& ( *(p+1) == 'm' || *(p+1) == 'M')
|
|
||||||
&& ( *(p+2) == 'l' || *(p+2) == 'L'))
|
|
||||||
{
|
{
|
||||||
if (*p == 'x')
|
if (*p == 'x')
|
||||||
appendStringInfo(&buf, "_x0078_");
|
appendStringInfo(&buf, "_x0078_");
|
||||||
@ -932,8 +890,9 @@ map_sql_identifier_to_xml_name(char *ident, bool fully_escaped)
|
|||||||
{
|
{
|
||||||
pg_wchar u = sqlchar_to_unicode(p);
|
pg_wchar u = sqlchar_to_unicode(p);
|
||||||
|
|
||||||
if (!is_valid_xml_namechar(u)
|
if ((p == ident)
|
||||||
|| (p == ident && !is_valid_xml_namefirst(u)))
|
? !is_valid_xml_namefirst(u)
|
||||||
|
: !is_valid_xml_namechar(u))
|
||||||
appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
|
appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
|
||||||
else
|
else
|
||||||
appendBinaryStringInfo(&buf, p, pg_mblen(p));
|
appendBinaryStringInfo(&buf, p, pg_mblen(p));
|
||||||
|
@ -37,7 +37,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/catversion.h,v 1.365 2006/12/23 00:43:12 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.366 2006/12/24 00:29:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200612221
|
#define CATALOG_VERSION_NO 200612231
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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.431 2006/12/21 16:05:15 petere Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.432 2006/12/24 00:29:19 tgl 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
|
||||||
@ -3983,17 +3983,9 @@ DATA(insert OID = 2894 ( xml_out PGNSP PGUID 12 f f t f i 1 2275 "142" _nul
|
|||||||
DESCR("I/O");
|
DESCR("I/O");
|
||||||
DATA(insert OID = 2895 ( xmlcomment PGNSP PGUID 12 f f t f i 1 142 "25" _null_ _null_ _null_ xmlcomment - _null_ ));
|
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");
|
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_ ));
|
DATA(insert OID = 2896 ( xml PGNSP PGUID 12 f f t f i 1 142 "25" _null_ _null_ _null_ texttoxml - _null_ ));
|
||||||
DESCR("perform a non-validating parse of a character string to produce an XML value");
|
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_ ));
|
DATA(insert OID = 2897 ( xmlvalidate PGNSP PGUID 12 f f t f i 2 16 "142 25" _null_ _null_ _null_ xmlvalidate - _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");
|
DESCR("validate an XML value");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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.163 2006/12/21 16:05:16 petere Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.164 2006/12/24 00:29:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -710,6 +710,18 @@ typedef struct MinMaxExprState
|
|||||||
FmgrInfo cfunc; /* lookup info for comparison func */
|
FmgrInfo cfunc; /* lookup info for comparison func */
|
||||||
} MinMaxExprState;
|
} MinMaxExprState;
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* XmlExprState node
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
typedef struct XmlExprState
|
||||||
|
{
|
||||||
|
ExprState xprstate;
|
||||||
|
List *named_args; /* ExprStates for named arguments */
|
||||||
|
FmgrInfo *named_outfuncs; /* array of output fns for named arguments */
|
||||||
|
List *args; /* ExprStates for other arguments */
|
||||||
|
} XmlExprState;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* NullTestState node
|
* NullTestState node
|
||||||
* ----------------
|
* ----------------
|
||||||
@ -723,22 +735,6 @@ 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.189 2006/12/21 16:05:16 petere Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.190 2006/12/24 00:29:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -130,6 +130,7 @@ typedef enum NodeTag
|
|||||||
T_RowCompareExpr,
|
T_RowCompareExpr,
|
||||||
T_CoalesceExpr,
|
T_CoalesceExpr,
|
||||||
T_MinMaxExpr,
|
T_MinMaxExpr,
|
||||||
|
T_XmlExpr,
|
||||||
T_NullIfExpr,
|
T_NullIfExpr,
|
||||||
T_NullTest,
|
T_NullTest,
|
||||||
T_BooleanTest,
|
T_BooleanTest,
|
||||||
@ -140,7 +141,6 @@ 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)
|
||||||
@ -166,10 +166,10 @@ typedef enum NodeTag
|
|||||||
T_RowCompareExprState,
|
T_RowCompareExprState,
|
||||||
T_CoalesceExprState,
|
T_CoalesceExprState,
|
||||||
T_MinMaxExprState,
|
T_MinMaxExprState,
|
||||||
|
T_XmlExprState,
|
||||||
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.120 2006/12/23 00:43:13 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.121 2006/12/24 00:29:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -711,6 +711,33 @@ typedef struct MinMaxExpr
|
|||||||
List *args; /* the arguments */
|
List *args; /* the arguments */
|
||||||
} MinMaxExpr;
|
} MinMaxExpr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XmlExpr - various SQL/XML functions requiring special grammar productions
|
||||||
|
*
|
||||||
|
* 'name' carries the "NAME foo" argument (already XML-escaped).
|
||||||
|
* 'named_args' and 'arg_names' represent an xml_attribute list.
|
||||||
|
* 'args' carries all other arguments.
|
||||||
|
*/
|
||||||
|
typedef enum XmlExprOp
|
||||||
|
{
|
||||||
|
IS_XMLCONCAT, /* XMLCONCAT(args) */
|
||||||
|
IS_XMLELEMENT, /* XMLELEMENT(name, xml_attributes, args) */
|
||||||
|
IS_XMLFOREST, /* XMLFOREST(xml_attributes) */
|
||||||
|
IS_XMLPARSE, /* XMLPARSE(text, is_doc, preserve_ws) */
|
||||||
|
IS_XMLPI, /* XMLPI(name [, args]) */
|
||||||
|
IS_XMLROOT /* XMLROOT(xml, version, standalone) */
|
||||||
|
} XmlExprOp;
|
||||||
|
|
||||||
|
typedef struct XmlExpr
|
||||||
|
{
|
||||||
|
Expr xpr;
|
||||||
|
XmlExprOp op; /* xml function ID */
|
||||||
|
char *name; /* name in xml(NAME foo ...) syntaxes */
|
||||||
|
List *named_args; /* non-XML expressions for xml_attributes */
|
||||||
|
List *arg_names; /* parallel list of Value strings */
|
||||||
|
List *args; /* list of expressions */
|
||||||
|
} XmlExpr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NullIfExpr - a NULLIF expression
|
* NullIfExpr - a NULLIF expression
|
||||||
*
|
*
|
||||||
@ -765,26 +792,6 @@ 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.67 2006/12/21 16:05:16 petere Exp $
|
* $PostgreSQL: pgsql/src/include/parser/parse_coerce.h,v 1.68 2006/12/24 00:29:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -55,11 +55,8 @@ extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod,
|
|||||||
|
|
||||||
extern Node *coerce_to_boolean(ParseState *pstate, Node *node,
|
extern Node *coerce_to_boolean(ParseState *pstate, Node *node,
|
||||||
const char *constructName);
|
const char *constructName);
|
||||||
extern Node *coerce_to_integer(ParseState *pstate, Node *node,
|
extern Node *coerce_to_specific_type(ParseState *pstate, Node *node,
|
||||||
const char *constructName);
|
Oid targetTypeId,
|
||||||
extern Node *coerce_to_bigint(ParseState *pstate, Node *node,
|
|
||||||
const char *constructName);
|
|
||||||
extern Node *coerce_to_xml(ParseState *pstate, Node *node,
|
|
||||||
const char *constructName);
|
const char *constructName);
|
||||||
|
|
||||||
extern Oid select_common_type(List *typeids, const char *context);
|
extern Oid select_common_type(List *typeids, const char *context);
|
||||||
|
@ -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/utils/xml.h,v 1.2 2006/12/23 04:56:50 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.3 2006/12/24 00:29:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -27,11 +27,13 @@ typedef struct varlena xmltype;
|
|||||||
extern Datum xml_in(PG_FUNCTION_ARGS);
|
extern Datum xml_in(PG_FUNCTION_ARGS);
|
||||||
extern Datum xml_out(PG_FUNCTION_ARGS);
|
extern Datum xml_out(PG_FUNCTION_ARGS);
|
||||||
extern Datum xmlcomment(PG_FUNCTION_ARGS);
|
extern Datum xmlcomment(PG_FUNCTION_ARGS);
|
||||||
extern Datum xmlparse(PG_FUNCTION_ARGS);
|
extern Datum texttoxml(PG_FUNCTION_ARGS);
|
||||||
extern Datum xmlpi(PG_FUNCTION_ARGS);
|
|
||||||
extern Datum xmlroot(PG_FUNCTION_ARGS);
|
|
||||||
extern Datum xmlvalidate(PG_FUNCTION_ARGS);
|
extern Datum xmlvalidate(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
|
extern xmltype *xmlparse(text *data, bool is_doc, bool preserve_whitespace);
|
||||||
|
extern xmltype *xmlpi(char *target, text *arg);
|
||||||
|
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
|
||||||
|
|
||||||
extern char *map_sql_identifier_to_xml_name(char *ident, bool fully_escaped);
|
extern char *map_sql_identifier_to_xml_name(char *ident, bool fully_escaped);
|
||||||
|
|
||||||
#endif /* XML_H */
|
#endif /* XML_H */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.180 2006/10/04 00:30:13 momjian Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.181 2006/12/24 00:29:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -4493,6 +4493,18 @@ exec_simple_check_node(Node *node)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case T_XmlExpr:
|
||||||
|
{
|
||||||
|
XmlExpr *expr = (XmlExpr *) node;
|
||||||
|
|
||||||
|
if (!exec_simple_check_node((Node *) expr->named_args))
|
||||||
|
return FALSE;
|
||||||
|
if (!exec_simple_check_node((Node *) expr->args))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
case T_NullIfExpr:
|
case T_NullIfExpr:
|
||||||
{
|
{
|
||||||
NullIfExpr *expr = (NullIfExpr *) node;
|
NullIfExpr *expr = (NullIfExpr *) node;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2003-2006, PostgreSQL Global Development Group
|
* Copyright (c) 2003-2006, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.9 2006/06/16 23:29:27 tgl Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.10 2006/12/24 00:29:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -243,6 +243,22 @@
|
|||||||
"untranslatable_character", ERRCODE_UNTRANSLATABLE_CHARACTER
|
"untranslatable_character", ERRCODE_UNTRANSLATABLE_CHARACTER
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"invalid_xml_document", ERRCODE_INVALID_XML_DOCUMENT
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"invalid_xml_content", ERRCODE_INVALID_XML_CONTENT
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"invalid_xml_comment", ERRCODE_INVALID_XML_COMMENT
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"invalid_xml_processing_instruction", ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"integrity_constraint_violation", ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION
|
"integrity_constraint_violation", ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION
|
||||||
},
|
},
|
||||||
|
@ -74,7 +74,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 NOT IN ('xmlparse', 'xmlpi') AND
|
p1.prosrc = p2.prosrc 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
|
||||||
|
@ -77,7 +77,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 NOT IN ('xmlparse', 'xmlpi') AND
|
p1.prosrc = p2.prosrc 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user