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)