|
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 | staticvoiddblink_res_error(constchar*conname,PGresult*res,constchar*dblink_context_msg,boolfail);
|
102 | 102 | staticchar*get_connect_string(constchar*servername);
|
103 | 103 | staticchar*escape_param_str(constchar*from);
|
| 104 | +staticintget_nondropped_natts(Oidrelid); |
104 | 105 |
|
105 | 106 | /* Global */
|
106 | 107 | staticremoteConn*pconn=NULL;
|
@@ -1262,6 +1263,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
1262 | 1263 | intsrc_nitems;
|
1263 | 1264 | inttgt_nitems;
|
1264 | 1265 | char*sql;
|
| 1266 | +intnondropped_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 | int32pknumatts_tmp=PG_GETARG_INT32(2);
|
1356 | 1367 | ArrayType*tgt_pkattvals_arry=PG_GETARG_ARRAYTYPE_P(3);
|
| 1368 | +intnondropped_natts; |
1357 | 1369 | Oidrelid;
|
1358 | 1370 | int16pknumatts=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 | int32pknumatts_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 | +intnondropped_natts; |
1444 | 1466 | Oidrelid;
|
1445 | 1467 | int16pknumatts=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 | returnbuf->data;
|
2444 | 2475 | }
|
| 2476 | + |
| 2477 | +staticint |
| 2478 | +get_nondropped_natts(Oidrelid) |
| 2479 | +{ |
| 2480 | +intnondropped_natts=0; |
| 2481 | +TupleDesctupdesc; |
| 2482 | +Relationrel; |
| 2483 | +intnatts; |
| 2484 | +inti; |
| 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 | +returnnondropped_natts; |
| 2499 | +} |
| 2500 | + |