1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-15 19:15:29 +03:00

Check to ensure the number of primary key fields supplied does not

exceed the total number of non-dropped source table fields for
dblink_build_sql_*(). Addresses bug report from Rushabh Lathia.

Backpatch all the way to the 7.3 branch.
This commit is contained in:
Joe Conway 2010-02-03 23:02:28 +00:00
parent 572f4758c3
commit a0b3d52af1
3 changed files with 70 additions and 0 deletions

View File

@ -88,6 +88,7 @@ static Oid get_relid_from_relname(text *relname_text);
static char *generate_relation_name(Oid relid);
static char *connstr_strip_password(const char *connstr);
static void dblink_security_check(PGconn *conn, remoteConn *rcon, const char *connstr);
static int get_nondropped_natts(Oid relid);
/* Global */
List *res_id = NIL;
@ -985,6 +986,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
int16 typlen;
bool typbyval;
char typalign;
int nondropped_natts;
relname_text = PG_GETARG_TEXT_P(0);
@ -1016,6 +1018,15 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("number of key attributes must be > 0")));
/*
* ensure we don't ask for more pk attributes than we have
* non-dropped columns
*/
nondropped_natts = get_nondropped_natts(relid);
if (pknumatts > nondropped_natts)
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("number of primary key fields exceeds number of specified relation attributes")));
src_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4);
@ -1132,6 +1143,7 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
int16 typlen;
bool typbyval;
char typalign;
int nondropped_natts;
relname_text = PG_GETARG_TEXT_P(0);
@ -1163,6 +1175,15 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("number of key attributes must be > 0")));
/*
* ensure we don't ask for more pk attributes than we have
* non-dropped columns
*/
nondropped_natts = get_nondropped_natts(relid);
if (pknumatts > nondropped_natts)
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("number of primary key fields exceeds number of specified relation attributes")));
tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
/*
@ -1254,6 +1275,7 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
int16 typlen;
bool typbyval;
char typalign;
int nondropped_natts;
relname_text = PG_GETARG_TEXT_P(0);
@ -1285,6 +1307,15 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("number of key attributes must be > 0")));
/*
* ensure we don't ask for more pk attributes than we have
* non-dropped columns
*/
nondropped_natts = get_nondropped_natts(relid);
if (pknumatts > nondropped_natts)
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("number of primary key fields exceeds number of specified relation attributes")));
src_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4);
@ -2134,3 +2165,27 @@ dblink_security_check(PGconn *conn, remoteConn *rcon, const char *connstr)
PQfinish(conn);
}
}
static int
get_nondropped_natts(Oid relid)
{
int nondropped_natts = 0;
TupleDesc tupdesc;
Relation rel;
int natts;
int i;
rel = relation_open(relid, AccessShareLock);
tupdesc = rel->rd_att;
natts = tupdesc->natts;
for (i = 0; i < natts; i++)
{
if (tupdesc->attrs[i]->attisdropped)
continue;
nondropped_natts++;
}
relation_close(rel, AccessShareLock);
return nondropped_natts;
}

View File

@ -44,6 +44,9 @@ SELECT dblink_build_sql_insert('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
INSERT INTO foo(f1,f2,f3) VALUES('99','xyz','{a0,b0,c0}')
(1 row)
-- too many pk fields, should fail
SELECT dblink_build_sql_insert('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
ERROR: number of primary key fields exceeds number of specified relation attributes
-- build an update statement based on a local tuple,
-- replacing the primary key values with new ones
SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
@ -52,6 +55,9 @@ SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
UPDATE foo SET f1 = '99', f2 = 'xyz', f3 = '{a0,b0,c0}' WHERE f1 = '99' AND f2 = 'xyz'
(1 row)
-- too many pk fields, should fail
SELECT dblink_build_sql_update('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
ERROR: number of primary key fields exceeds number of specified relation attributes
-- build a delete statement based on a local tuple,
SELECT dblink_build_sql_delete('foo','1 2',2,'{"0", "a"}');
dblink_build_sql_delete
@ -59,6 +65,9 @@ SELECT dblink_build_sql_delete('foo','1 2',2,'{"0", "a"}');
DELETE FROM foo WHERE f1 = '0' AND f2 = 'a'
(1 row)
-- too many pk fields, should fail
SELECT dblink_build_sql_delete('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}');
ERROR: number of primary key fields exceeds number of specified relation attributes
-- retest using a quoted and schema qualified table
CREATE SCHEMA "MySchema";
CREATE TABLE "MySchema"."Foo"(f1 int, f2 text, f3 text[], primary key (f1,f2));

View File

@ -35,13 +35,19 @@ FROM dblink_get_pkey('foo');
-- build an insert statement based on a local tuple,
-- replacing the primary key values with new ones
SELECT dblink_build_sql_insert('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
-- too many pk fields, should fail
SELECT dblink_build_sql_insert('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
-- build an update statement based on a local tuple,
-- replacing the primary key values with new ones
SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
-- too many pk fields, should fail
SELECT dblink_build_sql_update('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
-- build a delete statement based on a local tuple,
SELECT dblink_build_sql_delete('foo','1 2',2,'{"0", "a"}');
-- too many pk fields, should fail
SELECT dblink_build_sql_delete('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}');
-- retest using a quoted and schema qualified table
CREATE SCHEMA "MySchema";