Skip to content

Commit 338a2cd

Browse files
committed
improve function set_init_callback(), other fixes
1 parent 6571c86 commit 338a2cd

File tree

3 files changed

+57
-52
lines changed

3 files changed

+57
-52
lines changed

expected/pathman_callbacks.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ INSERT INTO abc VALUES (201, 0);
150150
WARNING: callback arg: {"parent": "abc", "parttype": "2", "partition": "abc_3", "range_max": "301", "range_min": "201", "parent_schema": "public", "partition_schema": "public"}
151151
DROP FUNCTION callbacks.abc_on_part_created_callback(jsonb);
152152
INSERT INTO abc VALUES (301, 0);
153-
ERROR: create_partitions_internal(): callback function "]callbacks.abc_on_part_created_callback(jsonb)" doesn't exist
153+
ERROR: callback function "callbacks.abc_on_part_created_callback(jsonb)" does not exist
154154
CREATE OR REPLACE FUNCTION callbacks.abc_on_part_created_callback(
155155
args JSONB)
156156
RETURNS VOID AS $$

init.sql

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,19 +158,23 @@ CREATE OR REPLACE FUNCTION @extschema@.set_init_callback(
158158
RETURNS VOID AS
159159
$$
160160
DECLARE
161-
regproc_text TEXT;
161+
regproc_text TEXT := NULL;
162+
162163
BEGIN
164+
165+
/* Fetch schema-qualified name of callback */
163166
IF callback != 0 THEN
164-
EXECUTE 'SELECT quote_ident(nspname) || ''.'' || quote_ident(proname)'
165-
' || ''('' || (SELECT string_agg(x.argtype::regtype::text, '','')'
166-
' FROM unnest(proargtypes) AS x(argtype))'
167-
' || '')'''
168-
'FROM pg_proc p JOIN pg_namespace n ON n.oid=p.pronamespace WHERE p.oid=$1'
169-
INTO regproc_text
170-
USING callback;
171-
ELSE
172-
regproc_text := NULL;
167+
SELECT quote_ident(nspname) || '.' ||
168+
quote_ident(proname) || '(' ||
169+
(SELECT string_agg(x.argtype::REGTYPE::TEXT, ',')
170+
FROM unnest(proargtypes) AS x(argtype)) ||
171+
')'
172+
FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n
173+
ON n.oid = p.pronamespace
174+
WHERE p.oid = callback
175+
INTO regproc_text; /* <= result */
173176
END IF;
177+
174178
PERFORM @extschema@.pathman_set_param(relation, 'init_callback', regproc_text);
175179
END
176180
$$

src/partition_creation.c

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ static ObjectAddress create_table_using_stmt(CreateStmt *create_stmt,
7878
static void copy_foreign_keys(Oid parent_relid, Oid partition_oid);
7979
static void postprocess_child_table_and_atts(Oid parent_relid, Oid partition_relid);
8080

81-
static Oid text2regprocedure(text *proname_args);
81+
static Oid text_to_regprocedure(text *proname_args);
8282

8383
static Constraint *make_constraint_common(char *name, Node *raw_expr);
8484

@@ -400,19 +400,20 @@ create_partitions_for_value_internal(Oid relid, Datum value, Oid value_type)
400400
{
401401
ErrorData *edata;
402402

403+
/* Simply rethrow ERROR if we're in backend */
404+
if (!IsBackgroundWorker)
405+
PG_RE_THROW();
406+
403407
/* Switch to the original context & copy edata */
404408
MemoryContextSwitchTo(old_mcxt);
405409
edata = CopyErrorData();
406410
FlushErrorState();
407411

408-
if (IsBackgroundWorker)
409-
ereport(LOG,
410-
(errmsg("create_partitions_internal(): %s [%u]", edata->message, MyProcPid),
411-
(edata->detail) ? errdetail("%s", edata->detail) : 0));
412-
else
413-
ereport(ERROR,
414-
(errmsg("create_partitions_internal(): %s", edata->message),
415-
(edata->detail) ? errdetail("%s", edata->detail) : 0));
412+
/* Produce log message if we're in BGW */
413+
ereport(LOG,
414+
(errmsg(CppAsString(create_partitions_for_value_internal) ": %s [%u]",
415+
edata->message, MyProcPid),
416+
(edata->detail) ? errdetail("%s", edata->detail) : 0));
416417

417418
FreeErrorData(edata);
418419

@@ -1391,34 +1392,6 @@ make_int_value_struct(int int_val)
13911392
return val;
13921393
}
13931394

1394-
/*
1395-
* Utility function that converts signature of procedure into regprocedure.
1396-
*
1397-
* Precondition: proc_signature != NULL.
1398-
*
1399-
* Returns InvalidOid if proname_args is not found.
1400-
* Raise error if it's incorrect.
1401-
*/
1402-
static Oid
1403-
text2regprocedure(text *proc_signature)
1404-
{
1405-
FunctionCallInfoData fcinfo;
1406-
Datum result;
1407-
1408-
InitFunctionCallInfoData(fcinfo, NULL, 1, InvalidOid, NULL, NULL);
1409-
1410-
#if PG_VERSION_NUM >= 90600
1411-
fcinfo.arg[0] = PointerGetDatum(proc_signature);
1412-
#else
1413-
fcinfo.arg[0] = CStringGetDatum(text_to_cstring(proc_signature));
1414-
#endif
1415-
fcinfo.argnull[0] = false;
1416-
1417-
result = to_regprocedure(&fcinfo);
1418-
1419-
return DatumGetObjectId(result);
1420-
}
1421-
14221395

14231396
/*
14241397
* ---------------------
@@ -1467,14 +1440,14 @@ invoke_init_callback_internal(init_callback_params *cb_params)
14671440
/* Cache init_callback's Oid */
14681441
if (init_cb_datum)
14691442
{
1470-
cb_params->callback = text2regprocedure(
1471-
DatumGetTextP(init_cb_datum));
1443+
/* Try fetching callback's Oid */
1444+
cb_params->callback = text_to_regprocedure(DatumGetTextP(init_cb_datum));
14721445

14731446
if (!RegProcedureIsValid(cb_params->callback))
14741447
ereport(ERROR,
14751448
(errcode(ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION),
1476-
errmsg("callback function \"%s\" doesn't exist",
1477-
DatumGetCString(init_cb_datum))));
1449+
errmsg("callback function \"%s\" does not exist",
1450+
TextDatumGetCString(init_cb_datum))));
14781451
}
14791452
else
14801453
cb_params->callback = InvalidOid;
@@ -1609,3 +1582,31 @@ validate_part_callback(Oid procid, bool emit_error)
16091582

16101583
return is_ok;
16111584
}
1585+
1586+
/*
1587+
* Utility function that converts signature of procedure into regprocedure.
1588+
*
1589+
* Precondition: proc_signature != NULL.
1590+
*
1591+
* Returns InvalidOid if proname_args is not found.
1592+
* Raise error if it's incorrect.
1593+
*/
1594+
static Oid
1595+
text_to_regprocedure(text *proc_signature)
1596+
{
1597+
FunctionCallInfoData fcinfo;
1598+
Datum result;
1599+
1600+
InitFunctionCallInfoData(fcinfo, NULL, 1, InvalidOid, NULL, NULL);
1601+
1602+
#if PG_VERSION_NUM >= 90600
1603+
fcinfo.arg[0] = PointerGetDatum(proc_signature);
1604+
#else
1605+
fcinfo.arg[0] = CStringGetDatum(text_to_cstring(proc_signature));
1606+
#endif
1607+
fcinfo.argnull[0] = false;
1608+
1609+
result = to_regprocedure(&fcinfo);
1610+
1611+
return DatumGetObjectId(result);
1612+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy