|
8 | 8 | * Darko Prenosil <Darko.Prenosil@finteh.hr>
|
9 | 9 | * Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
|
10 | 10 | *
|
11 |
| - * $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.87 2010/01/24 22:19:38 joe Exp $ |
| 11 | + * $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.88 2010/02/03 23:01:11 joe Exp $ |
12 | 12 | * Copyright (c) 2001-2010, PostgreSQL Global Development Group
|
13 | 13 | * ALL RIGHTS RESERVED;
|
14 | 14 | *
|
@@ -101,6 +101,7 @@ static void dblink_security_check(PGconn *conn, remoteConn *rconn);
|
101 | 101 | static void dblink_res_error(const char *conname, PGresult *res, const char *dblink_context_msg, bool fail);
|
102 | 102 | static char *get_connect_string(const char *servername);
|
103 | 103 | static char *escape_param_str(const char *from);
|
| 104 | +static int get_nondropped_natts(Oid relid); |
104 | 105 |
|
105 | 106 | /* Global */
|
106 | 107 | static remoteConn *pconn = NULL;
|
@@ -1262,6 +1263,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
1262 | 1263 | int src_nitems;
|
1263 | 1264 | int tgt_nitems;
|
1264 | 1265 | char *sql;
|
| 1266 | + int nondropped_natts; |
1265 | 1267 |
|
1266 | 1268 | /*
|
1267 | 1269 | * Convert relname to rel OID.
|
@@ -1289,6 +1291,15 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
1289 | 1291 | errmsg("input for number of primary key " \
|
1290 | 1292 | "attributes too large")));
|
1291 | 1293 |
|
| 1294 | + /* |
| 1295 | + * ensure we don't ask for more pk attributes than we have |
| 1296 | + * non-dropped columns |
| 1297 | + */ |
| 1298 | + nondropped_natts = get_nondropped_natts(relid); |
| 1299 | + if (pknumatts > nondropped_natts) |
| 1300 | + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), |
| 1301 | + errmsg("number of primary key fields exceeds number of specified relation attributes"))); |
| 1302 | + |
1292 | 1303 | /*
|
1293 | 1304 | * Source array is made up of key values that will be used to locate the
|
1294 | 1305 | * tuple of interest from the local system.
|
@@ -1354,6 +1365,7 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
|
1354 | 1365 | int2vector *pkattnums = (int2vector *) PG_GETARG_POINTER(1);
|
1355 | 1366 | int32 pknumatts_tmp = PG_GETARG_INT32(2);
|
1356 | 1367 | ArrayType *tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
|
| 1368 | + int nondropped_natts; |
1357 | 1369 | Oid relid;
|
1358 | 1370 | int16 pknumatts = 0;
|
1359 | 1371 | char **tgt_pkattvals;
|
@@ -1386,6 +1398,15 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
|
1386 | 1398 | errmsg("input for number of primary key " \
|
1387 | 1399 | "attributes too large")));
|
1388 | 1400 |
|
| 1401 | + /* |
| 1402 | + * ensure we don't ask for more pk attributes than we have |
| 1403 | + * non-dropped columns |
| 1404 | + */ |
| 1405 | + nondropped_natts = get_nondropped_natts(relid); |
| 1406 | + if (pknumatts > nondropped_natts) |
| 1407 | + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), |
| 1408 | + errmsg("number of primary key fields exceeds number of specified relation attributes"))); |
| 1409 | + |
1389 | 1410 | /*
|
1390 | 1411 | * Target array is made up of key values that will be used to build the
|
1391 | 1412 | * SQL string for use on the remote system.
|
@@ -1441,6 +1462,7 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
|
1441 | 1462 | int32 pknumatts_tmp = PG_GETARG_INT32(2);
|
1442 | 1463 | ArrayType *src_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
|
1443 | 1464 | ArrayType *tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4);
|
| 1465 | + int nondropped_natts; |
1444 | 1466 | Oid relid;
|
1445 | 1467 | int16 pknumatts = 0;
|
1446 | 1468 | char **src_pkattvals;
|
@@ -1475,6 +1497,15 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
|
1475 | 1497 | errmsg("input for number of primary key " \
|
1476 | 1498 | "attributes too large")));
|
1477 | 1499 |
|
| 1500 | + /* |
| 1501 | + * ensure we don't ask for more pk attributes than we have |
| 1502 | + * non-dropped columns |
| 1503 | + */ |
| 1504 | + nondropped_natts = get_nondropped_natts(relid); |
| 1505 | + if (pknumatts > nondropped_natts) |
| 1506 | + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), |
| 1507 | + errmsg("number of primary key fields exceeds number of specified relation attributes"))); |
| 1508 | + |
1478 | 1509 | /*
|
1479 | 1510 | * Source array is made up of key values that will be used to locate the
|
1480 | 1511 | * tuple of interest from the local system.
|
@@ -2442,3 +2473,28 @@ escape_param_str(const char *str)
|
2442 | 2473 |
|
2443 | 2474 | return buf->data;
|
2444 | 2475 | }
|
| 2476 | + |
| 2477 | +static int |
| 2478 | +get_nondropped_natts(Oid relid) |
| 2479 | +{ |
| 2480 | + int nondropped_natts = 0; |
| 2481 | + TupleDesc tupdesc; |
| 2482 | + Relation rel; |
| 2483 | + int natts; |
| 2484 | + int i; |
| 2485 | + |
| 2486 | + rel = relation_open(relid, AccessShareLock); |
| 2487 | + tupdesc = rel->rd_att; |
| 2488 | + natts = tupdesc->natts; |
| 2489 | + |
| 2490 | + for (i = 0; i < natts; i++) |
| 2491 | + { |
| 2492 | + if (tupdesc->attrs[i]->attisdropped) |
| 2493 | + continue; |
| 2494 | + nondropped_natts++; |
| 2495 | + } |
| 2496 | + |
| 2497 | + relation_close(rel, AccessShareLock); |
| 2498 | + return nondropped_natts; |
| 2499 | +} |
| 2500 | + |
0 commit comments