@@ -1360,136 +1360,6 @@ PLy_procedure_get(Oid fn_oid, bool is_trigger)
13601360 return entry -> proc ;
13611361}
13621362
1363- /*
1364- * Set up output conversion functions for a procedure
1365- */
1366- static void
1367- PLy_procedure_output_conversion (PLyProcedure * proc , Form_pg_proc procStruct )
1368- {
1369- HeapTuple rvTypeTup ;
1370- Form_pg_type rvTypeStruct ;
1371-
1372- /* Get the return type */
1373- rvTypeTup = SearchSysCache1 (TYPEOID ,
1374- ObjectIdGetDatum (procStruct -> prorettype ));
1375- if (!HeapTupleIsValid (rvTypeTup ))
1376- elog (ERROR , "cache lookup failed for type %u" ,
1377- procStruct -> prorettype );
1378- rvTypeStruct = (Form_pg_type ) GETSTRUCT (rvTypeTup );
1379-
1380- /* Disallow pseudotype result, except for void */
1381- if (rvTypeStruct -> typtype == TYPTYPE_PSEUDO &&
1382- procStruct -> prorettype != VOIDOID )
1383- {
1384- if (procStruct -> prorettype == TRIGGEROID )
1385- ereport (ERROR ,
1386- (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1387- errmsg ("trigger functions can only be called as triggers" )));
1388- else
1389- ereport (ERROR ,
1390- (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1391- errmsg ("PL/Python functions cannot return type %s" ,
1392- format_type_be (procStruct -> prorettype ))));
1393- }
1394-
1395- if (rvTypeStruct -> typtype == TYPTYPE_COMPOSITE )
1396- {
1397- /*
1398- * Tuple: set up later, during first call to
1399- * PLy_function_handler
1400- */
1401- proc -> result .out .d .typoid = procStruct -> prorettype ;
1402- proc -> result .is_rowtype = 2 ;
1403- }
1404- else
1405- {
1406- /* Do the real work */
1407- PLy_output_datum_func (& proc -> result , rvTypeTup );
1408- }
1409-
1410- ReleaseSysCache (rvTypeTup );
1411- }
1412-
1413- /*
1414- * Set up output conversion functions for a procedure
1415- */
1416- static void
1417- PLy_procedure_input_conversion (PLyProcedure * proc , HeapTuple procTup ,
1418- Form_pg_proc procStruct )
1419- {
1420- Oid * types ;
1421- char * * names ,
1422- * modes ;
1423- int i ,
1424- pos ,
1425- total ;
1426-
1427- /* Extract argument type info from the pg_proc tuple */
1428- total = get_func_arg_info (procTup , & types , & names , & modes );
1429-
1430- /* Count number of in+inout args into proc->nargs */
1431- if (modes == NULL )
1432- proc -> nargs = total ;
1433- else
1434- {
1435- /* proc->nargs was initialized to 0 above */
1436- for (i = 0 ; i < total ; i ++ )
1437- {
1438- if (modes [i ] != PROARGMODE_OUT &&
1439- modes [i ] != PROARGMODE_TABLE )
1440- (proc -> nargs )++ ;
1441- }
1442- }
1443-
1444- proc -> argnames = (char * * ) PLy_malloc0 (sizeof (char * ) * proc -> nargs );
1445- for (i = pos = 0 ; i < total ; i ++ )
1446- {
1447- HeapTuple argTypeTup ;
1448- Form_pg_type argTypeStruct ;
1449-
1450- if (modes &&
1451- (modes [i ] == PROARGMODE_OUT ||
1452- modes [i ] == PROARGMODE_TABLE ))
1453- continue ; /* skip OUT arguments */
1454-
1455- Assert (types [i ] == procStruct -> proargtypes .values [pos ]);
1456-
1457- argTypeTup = SearchSysCache1 (TYPEOID ,
1458- ObjectIdGetDatum (types [i ]));
1459- if (!HeapTupleIsValid (argTypeTup ))
1460- elog (ERROR , "cache lookup failed for type %u" , types [i ]);
1461- argTypeStruct = (Form_pg_type ) GETSTRUCT (argTypeTup );
1462-
1463- /* Check argument type is OK, set up I/O function info */
1464- switch (argTypeStruct -> typtype )
1465- {
1466- case TYPTYPE_PSEUDO :
1467- /* Disallow pseudotype argument */
1468- ereport (ERROR ,
1469- (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1470- errmsg ("PL/Python functions cannot accept type %s" ,
1471- format_type_be (types [i ]))));
1472- break ;
1473- case TYPTYPE_COMPOSITE :
1474- /* We'll set IO funcs at first call */
1475- proc -> args [pos ].is_rowtype = 2 ;
1476- break ;
1477- default :
1478- PLy_input_datum_func (& (proc -> args [pos ]),
1479- types [i ],
1480- argTypeTup );
1481- break ;
1482- }
1483-
1484- /* Get argument name */
1485- proc -> argnames [pos ] = names ? PLy_strdup (names [i ]) : NULL ;
1486-
1487- ReleaseSysCache (argTypeTup );
1488-
1489- pos ++ ;
1490- }
1491- }
1492-
14931363/*
14941364 * Create a new PLyProcedure structure
14951365 */
@@ -1538,7 +1408,46 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
15381408 * but only if this isn't a trigger.
15391409 */
15401410 if (!is_trigger )
1541- PLy_procedure_output_conversion (proc , procStruct );
1411+ {
1412+ HeapTuple rvTypeTup ;
1413+ Form_pg_type rvTypeStruct ;
1414+
1415+ rvTypeTup = SearchSysCache1 (TYPEOID ,
1416+ ObjectIdGetDatum (procStruct -> prorettype ));
1417+ if (!HeapTupleIsValid (rvTypeTup ))
1418+ elog (ERROR , "cache lookup failed for type %u" ,
1419+ procStruct -> prorettype );
1420+ rvTypeStruct = (Form_pg_type ) GETSTRUCT (rvTypeTup );
1421+
1422+ /* Disallow pseudotype result, except for void */
1423+ if (rvTypeStruct -> typtype == TYPTYPE_PSEUDO &&
1424+ procStruct -> prorettype != VOIDOID )
1425+ {
1426+ if (procStruct -> prorettype == TRIGGEROID )
1427+ ereport (ERROR ,
1428+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1429+ errmsg ("trigger functions can only be called as triggers" )));
1430+ else
1431+ ereport (ERROR ,
1432+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1433+ errmsg ("PL/Python functions cannot return type %s" ,
1434+ format_type_be (procStruct -> prorettype ))));
1435+ }
1436+
1437+ if (rvTypeStruct -> typtype == TYPTYPE_COMPOSITE )
1438+ {
1439+ /*
1440+ * Tuple: set up later, during first call to
1441+ * PLy_function_handler
1442+ */
1443+ proc -> result .out .d .typoid = procStruct -> prorettype ;
1444+ proc -> result .is_rowtype = 2 ;
1445+ }
1446+ else
1447+ PLy_output_datum_func (& proc -> result , rvTypeTup );
1448+
1449+ ReleaseSysCache (rvTypeTup );
1450+ }
15421451
15431452 /*
15441453 * Now get information required for input conversion of the
@@ -1548,7 +1457,79 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
15481457 * arguments.
15491458 */
15501459 if (procStruct -> pronargs )
1551- PLy_procedure_input_conversion (proc , procTup , procStruct );
1460+ {
1461+ Oid * types ;
1462+ char * * names ,
1463+ * modes ;
1464+ int i ,
1465+ pos ,
1466+ total ;
1467+
1468+ /* extract argument type info from the pg_proc tuple */
1469+ total = get_func_arg_info (procTup , & types , & names , & modes );
1470+
1471+ /* count number of in+inout args into proc->nargs */
1472+ if (modes == NULL )
1473+ proc -> nargs = total ;
1474+ else
1475+ {
1476+ /* proc->nargs was initialized to 0 above */
1477+ for (i = 0 ; i < total ; i ++ )
1478+ {
1479+ if (modes [i ] != PROARGMODE_OUT &&
1480+ modes [i ] != PROARGMODE_TABLE )
1481+ (proc -> nargs )++ ;
1482+ }
1483+ }
1484+
1485+ proc -> argnames = (char * * ) PLy_malloc0 (sizeof (char * ) * proc -> nargs );
1486+ for (i = pos = 0 ; i < total ; i ++ )
1487+ {
1488+ HeapTuple argTypeTup ;
1489+ Form_pg_type argTypeStruct ;
1490+
1491+ if (modes &&
1492+ (modes [i ] == PROARGMODE_OUT ||
1493+ modes [i ] == PROARGMODE_TABLE ))
1494+ continue ; /* skip OUT arguments */
1495+
1496+ Assert (types [i ] == procStruct -> proargtypes .values [pos ]);
1497+
1498+ argTypeTup = SearchSysCache1 (TYPEOID ,
1499+ ObjectIdGetDatum (types [i ]));
1500+ if (!HeapTupleIsValid (argTypeTup ))
1501+ elog (ERROR , "cache lookup failed for type %u" , types [i ]);
1502+ argTypeStruct = (Form_pg_type ) GETSTRUCT (argTypeTup );
1503+
1504+ /* check argument type is OK, set up I/O function info */
1505+ switch (argTypeStruct -> typtype )
1506+ {
1507+ case TYPTYPE_PSEUDO :
1508+ /* Disallow pseudotype argument */
1509+ ereport (ERROR ,
1510+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1511+ errmsg ("PL/Python functions cannot accept type %s" ,
1512+ format_type_be (types [i ]))));
1513+ break ;
1514+ case TYPTYPE_COMPOSITE :
1515+ /* we'll set IO funcs at first call */
1516+ proc -> args [pos ].is_rowtype = 2 ;
1517+ break ;
1518+ default :
1519+ PLy_input_datum_func (& (proc -> args [pos ]),
1520+ types [i ],
1521+ argTypeTup );
1522+ break ;
1523+ }
1524+
1525+ /* get argument name */
1526+ proc -> argnames [pos ] = names ? PLy_strdup (names [i ]) : NULL ;
1527+
1528+ ReleaseSysCache (argTypeTup );
1529+
1530+ pos ++ ;
1531+ }
1532+ }
15521533
15531534 /*
15541535 * get the text of the function.
0 commit comments