mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +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:
@ -8,7 +8,7 @@
|
||||
* Darko Prenosil <Darko.Prenosil@finteh.hr>
|
||||
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.87 2010/01/24 22:19:38 joe Exp $
|
||||
* $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.88 2010/02/03 23:01:11 joe Exp $
|
||||
* Copyright (c) 2001-2010, PostgreSQL Global Development Group
|
||||
* ALL RIGHTS RESERVED;
|
||||
*
|
||||
@ -101,6 +101,7 @@ static void dblink_security_check(PGconn *conn, remoteConn *rconn);
|
||||
static void dblink_res_error(const char *conname, PGresult *res, const char *dblink_context_msg, bool fail);
|
||||
static char *get_connect_string(const char *servername);
|
||||
static char *escape_param_str(const char *from);
|
||||
static int get_nondropped_natts(Oid relid);
|
||||
|
||||
/* Global */
|
||||
static remoteConn *pconn = NULL;
|
||||
@ -1262,6 +1263,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
||||
int src_nitems;
|
||||
int tgt_nitems;
|
||||
char *sql;
|
||||
int nondropped_natts;
|
||||
|
||||
/*
|
||||
* Convert relname to rel OID.
|
||||
@ -1289,6 +1291,15 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
||||
errmsg("input for number of primary key " \
|
||||
"attributes too large")));
|
||||
|
||||
/*
|
||||
* 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")));
|
||||
|
||||
/*
|
||||
* Source array is made up of key values that will be used to locate the
|
||||
* tuple of interest from the local system.
|
||||
@ -1354,6 +1365,7 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
|
||||
int2vector *pkattnums = (int2vector *) PG_GETARG_POINTER(1);
|
||||
int32 pknumatts_tmp = PG_GETARG_INT32(2);
|
||||
ArrayType *tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
|
||||
int nondropped_natts;
|
||||
Oid relid;
|
||||
int16 pknumatts = 0;
|
||||
char **tgt_pkattvals;
|
||||
@ -1386,6 +1398,15 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
|
||||
errmsg("input for number of primary key " \
|
||||
"attributes too large")));
|
||||
|
||||
/*
|
||||
* 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")));
|
||||
|
||||
/*
|
||||
* Target array is made up of key values that will be used to build the
|
||||
* SQL string for use on the remote system.
|
||||
@ -1441,6 +1462,7 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
|
||||
int32 pknumatts_tmp = PG_GETARG_INT32(2);
|
||||
ArrayType *src_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
|
||||
ArrayType *tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4);
|
||||
int nondropped_natts;
|
||||
Oid relid;
|
||||
int16 pknumatts = 0;
|
||||
char **src_pkattvals;
|
||||
@ -1475,6 +1497,15 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
|
||||
errmsg("input for number of primary key " \
|
||||
"attributes too large")));
|
||||
|
||||
/*
|
||||
* 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")));
|
||||
|
||||
/*
|
||||
* Source array is made up of key values that will be used to locate the
|
||||
* tuple of interest from the local system.
|
||||
@ -2442,3 +2473,28 @@ escape_param_str(const char *str)
|
||||
|
||||
return buf->data;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user