Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6c61d7c

Browse files
author
Etsuro Fujita
committed
postgres_fdw: Remove duplicate code in DML execution callback functions.
postgresExecForeignInsert(), postgresExecForeignUpdate(), andpostgresExecForeignDelete() are coded almost identically, except thatpostgresExecForeignInsert() does not need CTID. Extract that code intoa separate function and use it in all the three function implementations.Author: Ashutosh BapatReviewed-By: Michael PaquierDiscussion:https://postgr.es/m/CAFjFpRcz8yoY7cBTYofcrCLwjaDeCcGKyTUivUbRiA57y3v-bw%40mail.gmail.com
1 parentd723f56 commit6c61d7c

File tree

1 file changed

+103
-180
lines changed

1 file changed

+103
-180
lines changed

‎contrib/postgres_fdw/postgres_fdw.c

Lines changed: 103 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,11 @@ static PgFdwModifyState *create_foreign_modify(EState *estate,
391391
List*target_attrs,
392392
boolhas_returning,
393393
List*retrieved_attrs);
394+
staticTupleTableSlot*execute_foreign_modify(EState*estate,
395+
ResultRelInfo*resultRelInfo,
396+
CmdTypeoperation,
397+
TupleTableSlot*slot,
398+
TupleTableSlot*planSlot);
394399
staticvoidprepare_foreign_modify(PgFdwModifyState*fmstate);
395400
staticconstchar**convert_prep_stmt_params(PgFdwModifyState*fmstate,
396401
ItemPointertupleid,
@@ -1776,58 +1781,8 @@ postgresExecForeignInsert(EState *estate,
17761781
TupleTableSlot*slot,
17771782
TupleTableSlot*planSlot)
17781783
{
1779-
PgFdwModifyState*fmstate= (PgFdwModifyState*)resultRelInfo->ri_FdwState;
1780-
constchar**p_values;
1781-
PGresult*res;
1782-
intn_rows;
1783-
1784-
/* Set up the prepared statement on the remote server, if we didn't yet */
1785-
if (!fmstate->p_name)
1786-
prepare_foreign_modify(fmstate);
1787-
1788-
/* Convert parameters needed by prepared statement to text form */
1789-
p_values=convert_prep_stmt_params(fmstate,NULL,slot);
1790-
1791-
/*
1792-
* Execute the prepared statement.
1793-
*/
1794-
if (!PQsendQueryPrepared(fmstate->conn,
1795-
fmstate->p_name,
1796-
fmstate->p_nums,
1797-
p_values,
1798-
NULL,
1799-
NULL,
1800-
0))
1801-
pgfdw_report_error(ERROR,NULL,fmstate->conn, false,fmstate->query);
1802-
1803-
/*
1804-
* Get the result, and check for success.
1805-
*
1806-
* We don't use a PG_TRY block here, so be careful not to throw error
1807-
* without releasing the PGresult.
1808-
*/
1809-
res=pgfdw_get_result(fmstate->conn,fmstate->query);
1810-
if (PQresultStatus(res)!=
1811-
(fmstate->has_returning ?PGRES_TUPLES_OK :PGRES_COMMAND_OK))
1812-
pgfdw_report_error(ERROR,res,fmstate->conn, true,fmstate->query);
1813-
1814-
/* Check number of rows affected, and fetch RETURNING tuple if any */
1815-
if (fmstate->has_returning)
1816-
{
1817-
n_rows=PQntuples(res);
1818-
if (n_rows>0)
1819-
store_returning_result(fmstate,slot,res);
1820-
}
1821-
else
1822-
n_rows=atoi(PQcmdTuples(res));
1823-
1824-
/* And clean up */
1825-
PQclear(res);
1826-
1827-
MemoryContextReset(fmstate->temp_cxt);
1828-
1829-
/* Return NULL if nothing was inserted on the remote end */
1830-
return (n_rows>0) ?slot :NULL;
1784+
returnexecute_foreign_modify(estate,resultRelInfo,CMD_INSERT,
1785+
slot,planSlot);
18311786
}
18321787

18331788
/*
@@ -1840,70 +1795,8 @@ postgresExecForeignUpdate(EState *estate,
18401795
TupleTableSlot*slot,
18411796
TupleTableSlot*planSlot)
18421797
{
1843-
PgFdwModifyState*fmstate= (PgFdwModifyState*)resultRelInfo->ri_FdwState;
1844-
Datumdatum;
1845-
boolisNull;
1846-
constchar**p_values;
1847-
PGresult*res;
1848-
intn_rows;
1849-
1850-
/* Set up the prepared statement on the remote server, if we didn't yet */
1851-
if (!fmstate->p_name)
1852-
prepare_foreign_modify(fmstate);
1853-
1854-
/* Get the ctid that was passed up as a resjunk column */
1855-
datum=ExecGetJunkAttribute(planSlot,
1856-
fmstate->ctidAttno,
1857-
&isNull);
1858-
/* shouldn't ever get a null result... */
1859-
if (isNull)
1860-
elog(ERROR,"ctid is NULL");
1861-
1862-
/* Convert parameters needed by prepared statement to text form */
1863-
p_values=convert_prep_stmt_params(fmstate,
1864-
(ItemPointer)DatumGetPointer(datum),
1865-
slot);
1866-
1867-
/*
1868-
* Execute the prepared statement.
1869-
*/
1870-
if (!PQsendQueryPrepared(fmstate->conn,
1871-
fmstate->p_name,
1872-
fmstate->p_nums,
1873-
p_values,
1874-
NULL,
1875-
NULL,
1876-
0))
1877-
pgfdw_report_error(ERROR,NULL,fmstate->conn, false,fmstate->query);
1878-
1879-
/*
1880-
* Get the result, and check for success.
1881-
*
1882-
* We don't use a PG_TRY block here, so be careful not to throw error
1883-
* without releasing the PGresult.
1884-
*/
1885-
res=pgfdw_get_result(fmstate->conn,fmstate->query);
1886-
if (PQresultStatus(res)!=
1887-
(fmstate->has_returning ?PGRES_TUPLES_OK :PGRES_COMMAND_OK))
1888-
pgfdw_report_error(ERROR,res,fmstate->conn, true,fmstate->query);
1889-
1890-
/* Check number of rows affected, and fetch RETURNING tuple if any */
1891-
if (fmstate->has_returning)
1892-
{
1893-
n_rows=PQntuples(res);
1894-
if (n_rows>0)
1895-
store_returning_result(fmstate,slot,res);
1896-
}
1897-
else
1898-
n_rows=atoi(PQcmdTuples(res));
1899-
1900-
/* And clean up */
1901-
PQclear(res);
1902-
1903-
MemoryContextReset(fmstate->temp_cxt);
1904-
1905-
/* Return NULL if nothing was updated on the remote end */
1906-
return (n_rows>0) ?slot :NULL;
1798+
returnexecute_foreign_modify(estate,resultRelInfo,CMD_UPDATE,
1799+
slot,planSlot);
19071800
}
19081801

19091802
/*
@@ -1916,70 +1809,8 @@ postgresExecForeignDelete(EState *estate,
19161809
TupleTableSlot*slot,
19171810
TupleTableSlot*planSlot)
19181811
{
1919-
PgFdwModifyState*fmstate= (PgFdwModifyState*)resultRelInfo->ri_FdwState;
1920-
Datumdatum;
1921-
boolisNull;
1922-
constchar**p_values;
1923-
PGresult*res;
1924-
intn_rows;
1925-
1926-
/* Set up the prepared statement on the remote server, if we didn't yet */
1927-
if (!fmstate->p_name)
1928-
prepare_foreign_modify(fmstate);
1929-
1930-
/* Get the ctid that was passed up as a resjunk column */
1931-
datum=ExecGetJunkAttribute(planSlot,
1932-
fmstate->ctidAttno,
1933-
&isNull);
1934-
/* shouldn't ever get a null result... */
1935-
if (isNull)
1936-
elog(ERROR,"ctid is NULL");
1937-
1938-
/* Convert parameters needed by prepared statement to text form */
1939-
p_values=convert_prep_stmt_params(fmstate,
1940-
(ItemPointer)DatumGetPointer(datum),
1941-
NULL);
1942-
1943-
/*
1944-
* Execute the prepared statement.
1945-
*/
1946-
if (!PQsendQueryPrepared(fmstate->conn,
1947-
fmstate->p_name,
1948-
fmstate->p_nums,
1949-
p_values,
1950-
NULL,
1951-
NULL,
1952-
0))
1953-
pgfdw_report_error(ERROR,NULL,fmstate->conn, false,fmstate->query);
1954-
1955-
/*
1956-
* Get the result, and check for success.
1957-
*
1958-
* We don't use a PG_TRY block here, so be careful not to throw error
1959-
* without releasing the PGresult.
1960-
*/
1961-
res=pgfdw_get_result(fmstate->conn,fmstate->query);
1962-
if (PQresultStatus(res)!=
1963-
(fmstate->has_returning ?PGRES_TUPLES_OK :PGRES_COMMAND_OK))
1964-
pgfdw_report_error(ERROR,res,fmstate->conn, true,fmstate->query);
1965-
1966-
/* Check number of rows affected, and fetch RETURNING tuple if any */
1967-
if (fmstate->has_returning)
1968-
{
1969-
n_rows=PQntuples(res);
1970-
if (n_rows>0)
1971-
store_returning_result(fmstate,slot,res);
1972-
}
1973-
else
1974-
n_rows=atoi(PQcmdTuples(res));
1975-
1976-
/* And clean up */
1977-
PQclear(res);
1978-
1979-
MemoryContextReset(fmstate->temp_cxt);
1980-
1981-
/* Return NULL if nothing was deleted on the remote end */
1982-
return (n_rows>0) ?slot :NULL;
1812+
returnexecute_foreign_modify(estate,resultRelInfo,CMD_DELETE,
1813+
slot,planSlot);
19831814
}
19841815

19851816
/*
@@ -3425,6 +3256,98 @@ create_foreign_modify(EState *estate,
34253256
returnfmstate;
34263257
}
34273258

3259+
/*
3260+
* execute_foreign_modify
3261+
*Perform foreign-table modification as required, and fetch RETURNING
3262+
*result if any. (This is the shared guts of postgresExecForeignInsert,
3263+
*postgresExecForeignUpdate, and postgresExecForeignDelete.)
3264+
*/
3265+
staticTupleTableSlot*
3266+
execute_foreign_modify(EState*estate,
3267+
ResultRelInfo*resultRelInfo,
3268+
CmdTypeoperation,
3269+
TupleTableSlot*slot,
3270+
TupleTableSlot*planSlot)
3271+
{
3272+
PgFdwModifyState*fmstate= (PgFdwModifyState*)resultRelInfo->ri_FdwState;
3273+
ItemPointerctid=NULL;
3274+
constchar**p_values;
3275+
PGresult*res;
3276+
intn_rows;
3277+
3278+
/* The operation should be INSERT, UPDATE, or DELETE */
3279+
Assert(operation==CMD_INSERT||
3280+
operation==CMD_UPDATE||
3281+
operation==CMD_DELETE);
3282+
3283+
/* Set up the prepared statement on the remote server, if we didn't yet */
3284+
if (!fmstate->p_name)
3285+
prepare_foreign_modify(fmstate);
3286+
3287+
/*
3288+
* For UPDATE/DELETE, get the ctid that was passed up as a resjunk column
3289+
*/
3290+
if (operation==CMD_UPDATE||operation==CMD_DELETE)
3291+
{
3292+
Datumdatum;
3293+
boolisNull;
3294+
3295+
datum=ExecGetJunkAttribute(planSlot,
3296+
fmstate->ctidAttno,
3297+
&isNull);
3298+
/* shouldn't ever get a null result... */
3299+
if (isNull)
3300+
elog(ERROR,"ctid is NULL");
3301+
ctid= (ItemPointer)DatumGetPointer(datum);
3302+
}
3303+
3304+
/* Convert parameters needed by prepared statement to text form */
3305+
p_values=convert_prep_stmt_params(fmstate,ctid,slot);
3306+
3307+
/*
3308+
* Execute the prepared statement.
3309+
*/
3310+
if (!PQsendQueryPrepared(fmstate->conn,
3311+
fmstate->p_name,
3312+
fmstate->p_nums,
3313+
p_values,
3314+
NULL,
3315+
NULL,
3316+
0))
3317+
pgfdw_report_error(ERROR,NULL,fmstate->conn, false,fmstate->query);
3318+
3319+
/*
3320+
* Get the result, and check for success.
3321+
*
3322+
* We don't use a PG_TRY block here, so be careful not to throw error
3323+
* without releasing the PGresult.
3324+
*/
3325+
res=pgfdw_get_result(fmstate->conn,fmstate->query);
3326+
if (PQresultStatus(res)!=
3327+
(fmstate->has_returning ?PGRES_TUPLES_OK :PGRES_COMMAND_OK))
3328+
pgfdw_report_error(ERROR,res,fmstate->conn, true,fmstate->query);
3329+
3330+
/* Check number of rows affected, and fetch RETURNING tuple if any */
3331+
if (fmstate->has_returning)
3332+
{
3333+
n_rows=PQntuples(res);
3334+
if (n_rows>0)
3335+
store_returning_result(fmstate,slot,res);
3336+
}
3337+
else
3338+
n_rows=atoi(PQcmdTuples(res));
3339+
3340+
/* And clean up */
3341+
PQclear(res);
3342+
3343+
MemoryContextReset(fmstate->temp_cxt);
3344+
3345+
/*
3346+
* Return NULL if nothing was inserted/updated/deleted on the remote end
3347+
*/
3348+
return (n_rows>0) ?slot :NULL;
3349+
}
3350+
34283351
/*
34293352
* prepare_foreign_modify
34303353
*Establish a prepared statement for execution of INSERT/UPDATE/DELETE

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp