提交 1ccc3df7 编写于 作者: R Robert Haas 提交者: Jimmy Yih

Change various deparsing functions to return NULL for invalid input.

Previously, some functions returned various fixed strings and others
failed with a cache lookup error.  Per discussion, standardize on
returning NULL.  Although user-exposed "cache lookup failed" error
messages might normally qualify for bug-fix treatment, no back-patch;
the risk of breaking user code which is accustomed to the current
behavior seems too high.

Michael Paquier

Original Postgres commit:
https://github.com/postgres/postgres/commit/976b24fb477464907737d28cdf18e202fa3b1a5b
上级 3a2c6f67
......@@ -318,9 +318,9 @@ static char *pg_get_ruledef_worker(Oid ruleoid, int prettyFlags);
static char *pg_get_indexdef_worker(Oid indexrelid, int colno,
const Oid *excludeOps,
bool attrsOnly, bool showTblSpc,
int prettyFlags);
int prettyFlags, bool missing_ok);
static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
int prettyFlags);
int prettyFlags, bool missing_ok);
static text *pg_get_expr_worker(text *expr, Oid relid, const char *relname,
int prettyFlags);
static int print_function_arguments(StringInfo buf, HeapTuple proctup,
......@@ -466,9 +466,16 @@ pg_get_ruledef(PG_FUNCTION_ARGS)
{
Oid ruleoid = PG_GETARG_OID(0);
int prettyFlags;
char *res;
prettyFlags = PRETTYFLAG_INDENT;
PG_RETURN_TEXT_P(string_to_text(pg_get_ruledef_worker(ruleoid, prettyFlags)));
res = pg_get_ruledef_worker(ruleoid, prettyFlags);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
......@@ -478,10 +485,16 @@ pg_get_ruledef_ext(PG_FUNCTION_ARGS)
Oid ruleoid = PG_GETARG_OID(0);
bool pretty = PG_GETARG_BOOL(1);
int prettyFlags;
char *res;
prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
PG_RETURN_TEXT_P(string_to_text(pg_get_ruledef_worker(ruleoid, prettyFlags)));
res = pg_get_ruledef_worker(ruleoid, prettyFlags);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
......@@ -533,7 +546,12 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags)
if (spirc != SPI_OK_SELECT)
elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid);
if (SPI_processed != 1)
appendStringInfoChar(&buf, '-');
{
/*
* There is no tuple data available here, just keep the output buffer
* empty.
*/
}
else
{
/*
......@@ -550,6 +568,9 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags)
if (SPI_finish() != SPI_OK_FINISH)
elog(ERROR, "SPI_finish failed");
if (buf.len == 0)
return NULL;
return buf.data;
}
......@@ -565,9 +586,16 @@ pg_get_viewdef(PG_FUNCTION_ARGS)
/* By OID */
Oid viewoid = PG_GETARG_OID(0);
int prettyFlags;
char *res;
prettyFlags = PRETTYFLAG_INDENT;
PG_RETURN_TEXT_P(string_to_text(pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT)));
res = pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
......@@ -578,10 +606,16 @@ pg_get_viewdef_ext(PG_FUNCTION_ARGS)
Oid viewoid = PG_GETARG_OID(0);
bool pretty = PG_GETARG_BOOL(1);
int prettyFlags;
char *res;
prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
PG_RETURN_TEXT_P(string_to_text(pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT)));
res = pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
Datum
......@@ -591,11 +625,17 @@ pg_get_viewdef_wrap(PG_FUNCTION_ARGS)
Oid viewoid = PG_GETARG_OID(0);
int wrap = PG_GETARG_INT32(1);
int prettyFlags;
char *res;
/* calling this implies we want pretty printing */
prettyFlags = PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA;
PG_RETURN_TEXT_P(string_to_text(pg_get_viewdef_worker(viewoid, prettyFlags, wrap)));
res = pg_get_viewdef_worker(viewoid, prettyFlags, wrap);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
Datum
......@@ -606,6 +646,7 @@ pg_get_viewdef_name(PG_FUNCTION_ARGS)
int prettyFlags;
RangeVar *viewrel;
Oid viewoid;
char *res;
prettyFlags = PRETTYFLAG_INDENT;
......@@ -613,7 +654,12 @@ pg_get_viewdef_name(PG_FUNCTION_ARGS)
viewrel = makeRangeVarFromNameList(textToQualifiedNameList(viewname));
viewoid = RangeVarGetRelid(viewrel, NoLock, false);
PG_RETURN_TEXT_P(string_to_text(pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT)));
res = pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
......@@ -690,7 +736,12 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn)
if (spirc != SPI_OK_SELECT)
elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid);
if (SPI_processed != 1)
appendStringInfoString(&buf, "Not a view");
{
/*
* There is no tuple data available here, just keep the output buffer
* empty.
*/
}
else
{
/*
......@@ -707,6 +758,9 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn)
if (SPI_finish() != SPI_OK_FINISH)
elog(ERROR, "SPI_finish failed");
if (buf.len == 0)
return NULL;
return buf.data;
}
......@@ -718,8 +772,14 @@ Datum
pg_get_triggerdef(PG_FUNCTION_ARGS)
{
Oid trigid = PG_GETARG_OID(0);
char *res;
PG_RETURN_TEXT_P(string_to_text(pg_get_triggerdef_worker(trigid, false)));
res = pg_get_triggerdef_worker(trigid, false);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
Datum
......@@ -727,8 +787,14 @@ pg_get_triggerdef_ext(PG_FUNCTION_ARGS)
{
Oid trigid = PG_GETARG_OID(0);
bool pretty = PG_GETARG_BOOL(1);
char *res;
PG_RETURN_TEXT_P(string_to_text(pg_get_triggerdef_worker(trigid, pretty)));
res = pg_get_triggerdef_worker(trigid, pretty);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
static char *
......@@ -761,7 +827,11 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
ht_trig = systable_getnext(tgscan);
if (!HeapTupleIsValid(ht_trig))
elog(ERROR, "could not find tuple for trigger %u", trigid);
{
systable_endscan(tgscan);
heap_close(tgrel, AccessShareLock);
return NULL;
}
trigrec = (Form_pg_trigger) GETSTRUCT(ht_trig);
......@@ -976,12 +1046,17 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
{
Oid indexrelid = PG_GETARG_OID(0);
int prettyFlags;
char *res;
prettyFlags = PRETTYFLAG_INDENT;
PG_RETURN_TEXT_P(string_to_text(pg_get_indexdef_worker(indexrelid, 0,
NULL,
false, false,
prettyFlags)));
res = pg_get_indexdef_worker(indexrelid, 0, NULL, false, false,
prettyFlags, true);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
Datum
......@@ -991,14 +1066,17 @@ pg_get_indexdef_ext(PG_FUNCTION_ARGS)
int32 colno = PG_GETARG_INT32(1);
bool pretty = PG_GETARG_BOOL(2);
int prettyFlags;
char *res;
prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
PG_RETURN_TEXT_P(string_to_text(pg_get_indexdef_worker(indexrelid, colno,
NULL,
colno != 0,
false,
prettyFlags)));
res = pg_get_indexdef_worker(indexrelid, colno, NULL, colno != 0, false,
prettyFlags, true);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
/*
......@@ -1009,7 +1087,7 @@ pg_get_indexdef_ext(PG_FUNCTION_ARGS)
char *
pg_get_indexdef_string(Oid indexrelid)
{
return pg_get_indexdef_worker(indexrelid, 0, NULL, false, true, 0);
return pg_get_indexdef_worker(indexrelid, 0, NULL, false, true, 0, false);
}
/* Internal version that just reports the column definitions */
......@@ -1019,8 +1097,8 @@ pg_get_indexdef_columns(Oid indexrelid, bool pretty)
int prettyFlags;
prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
return pg_get_indexdef_worker(indexrelid, 0, NULL, true, false, prettyFlags);
return pg_get_indexdef_worker(indexrelid, 0, NULL, true, false,
prettyFlags, false);
}
/*
......@@ -1033,7 +1111,7 @@ static char *
pg_get_indexdef_worker(Oid indexrelid, int colno,
const Oid *excludeOps,
bool attrsOnly, bool showTblSpc,
int prettyFlags)
int prettyFlags, bool missing_ok)
{
/* might want a separate isConstraint parameter later */
bool isConstraint = (excludeOps != NULL);
......@@ -1065,9 +1143,9 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
ht_idx = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexrelid));
if (!HeapTupleIsValid(ht_idx))
{
/* Was: elog(ERROR, "cache lookup failed for index %u", indexrelid); */
/* See: MPP-10387. */
return pstrdup("Not an index");
if (missing_ok)
return NULL;
elog(ERROR, "cache lookup failed for index %u", indexrelid);
}
idxrec = (Form_pg_index) GETSTRUCT(ht_idx);
......@@ -1324,11 +1402,16 @@ pg_get_constraintdef(PG_FUNCTION_ARGS)
{
Oid constraintId = PG_GETARG_OID(0);
int prettyFlags;
char *res;
prettyFlags = PRETTYFLAG_INDENT;
PG_RETURN_TEXT_P(string_to_text(pg_get_constraintdef_worker(constraintId,
false,
prettyFlags)));
res = pg_get_constraintdef_worker(constraintId, false, prettyFlags, true);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
Datum
......@@ -1337,12 +1420,16 @@ pg_get_constraintdef_ext(PG_FUNCTION_ARGS)
Oid constraintId = PG_GETARG_OID(0);
bool pretty = PG_GETARG_BOOL(1);
int prettyFlags;
char *res;
prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
PG_RETURN_TEXT_P(string_to_text(pg_get_constraintdef_worker(constraintId,
false,
prettyFlags)));
res = pg_get_constraintdef_worker(constraintId, false, prettyFlags, true);
if (res == NULL)
PG_RETURN_NULL();
PG_RETURN_TEXT_P(string_to_text(res));
}
/*
......@@ -1351,14 +1438,14 @@ pg_get_constraintdef_ext(PG_FUNCTION_ARGS)
char *
pg_get_constraintdef_string(Oid constraintId)
{
return pg_get_constraintdef_worker(constraintId, true, 0);
return pg_get_constraintdef_worker(constraintId, true, 0, false);
}
/* Internal version that returns a palloc'd C string */
char *
pg_get_constraintexpr_string(Oid constraintId)
{
return pg_get_constraintdef_worker(constraintId, false, 0);
return pg_get_constraintdef_worker(constraintId, false, 0, false);
}
/*
......@@ -1366,7 +1453,7 @@ pg_get_constraintexpr_string(Oid constraintId)
*/
static char *
pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
int prettyFlags)
int prettyFlags, bool missing_ok)
{
HeapTuple tup;
Form_pg_constraint conForm;
......@@ -1396,8 +1483,16 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
UnregisterSnapshot(snapshot);
if (!HeapTupleIsValid(tup)) /* should not happen */
if (!HeapTupleIsValid(tup))
{
if (missing_ok)
{
systable_endscan(scandesc);
heap_close(relation, AccessShareLock);
return NULL;
}
elog(ERROR, "cache lookup failed for constraint %u", constraintId);
}
conForm = (Form_pg_constraint) GETSTRUCT(tup);
......@@ -1669,7 +1764,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
operators,
false,
false,
prettyFlags));
prettyFlags,
false));
break;
}
default:
......@@ -2024,7 +2120,8 @@ pg_get_functiondef(PG_FUNCTION_ARGS)
/* Look up the function */
proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
if (!HeapTupleIsValid(proctup))
elog(ERROR, "cache lookup failed for function %u", funcid);
PG_RETURN_NULL();
proc = (Form_pg_proc) GETSTRUCT(proctup);
name = NameStr(proc->proname);
......@@ -4396,7 +4493,7 @@ make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
if (list_length(actions) != 1)
{
appendStringInfoString(buf, "Not a view");
/* keep output buffer empty and leave */
return;
}
......@@ -4405,7 +4502,7 @@ make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
if (ev_type != '1' || !is_instead ||
strcmp(ev_qual, "<>") != 0 || query->commandType != CMD_SELECT)
{
appendStringInfoString(buf, "Not a view");
/* keep output buffer empty and leave */
return;
}
......
......@@ -2735,6 +2735,43 @@ SELECT pg_get_functiondef('func_with_set_params()'::regprocedure);
(1 row)
-- tests for pg_get_*def with invalid objects
SELECT pg_get_constraintdef(0);
pg_get_constraintdef
----------------------
(1 row)
SELECT pg_get_functiondef(0);
pg_get_functiondef
--------------------
(1 row)
SELECT pg_get_indexdef(0);
pg_get_indexdef
-----------------
(1 row)
SELECT pg_get_ruledef(0);
pg_get_ruledef
----------------
(1 row)
SELECT pg_get_triggerdef(0);
pg_get_triggerdef
-------------------
(1 row)
SELECT pg_get_viewdef(0);
pg_get_viewdef
----------------
(1 row)
-- test rule for select-for-update
create table t_test_rules_select_for_update (c int) distributed randomly;
create rule myrule as on insert to t_test_rules_select_for_update
......
......@@ -1036,6 +1036,14 @@ CREATE FUNCTION func_with_set_params() RETURNS integer
IMMUTABLE STRICT;
SELECT pg_get_functiondef('func_with_set_params()'::regprocedure);
-- tests for pg_get_*def with invalid objects
SELECT pg_get_constraintdef(0);
SELECT pg_get_functiondef(0);
SELECT pg_get_indexdef(0);
SELECT pg_get_ruledef(0);
SELECT pg_get_triggerdef(0);
SELECT pg_get_viewdef(0);
-- test rule for select-for-update
create table t_test_rules_select_for_update (c int) distributed randomly;
create rule myrule as on insert to t_test_rules_select_for_update
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册