Improve support for handling IN / named params in functions
authorRobert Treat <rob@xzilla.net>
Sat, 22 Feb 2014 18:45:37 +0000 (13:45 -0500)
committerRobert Treat <rob@xzilla.net>
Sat, 22 Feb 2014 18:45:37 +0000 (13:45 -0500)
Based on work by Bert Thomas <bthomas@brothom.nl>

classes/database/Postgres.php
classes/database/Postgres83.php
functions.php

index 4ab71646ad54fccfb6aba6eb1cbe718d90f66c12..1d72db0e44b5c619d02bbc20072835a13c78566a 100755 (executable)
@@ -4112,14 +4112,19 @@ class Postgres extends ADODB_base {
 
                $sql = "
                        SELECT
-                               pc.oid AS prooid, proname, pg_catalog.pg_get_userbyid(proowner) AS proowner,
+                               pc.oid AS prooid, proname, 
+                pg_catalog.pg_get_userbyid(proowner) AS proowner,
                                nspname as proschema, lanname as prolanguage, procost, prorows,
                                pg_catalog.format_type(prorettype, NULL) as proresult, prosrc,
                                probin, proretset, proisstrict, provolatile, prosecdef,
                                pg_catalog.oidvectortypes(pc.proargtypes) AS proarguments,
                                proargnames AS proargnames,
                                pg_catalog.obj_description(pc.oid, 'pg_proc') AS procomment,
-                               proconfig
+                               proconfig,
+                (select array_agg( (select typname from pg_type pt 
+                    where pt.oid = p.oid) ) from unnest(proallargtypes) p) 
+                AS proallarguments,
+                proargmodes
                        FROM
                                pg_catalog.pg_proc pc, pg_catalog.pg_language pl,
                                pg_catalog.pg_namespace pn
index 3ac4f78924383670690df4e53355f04597ba49bc..ce0416b9223a7a97ffa20f0216fe15b24c2593c8 100644 (file)
@@ -322,6 +322,39 @@ class Postgres83 extends Postgres84 {
                return 0;
        }
 
+       // Function functions
+
+       /**
+        * Returns all details for a particular function
+        * @param $func The name of the function to retrieve
+        * @return Function info
+        */
+       function getFunction($function_oid) {
+               $this->clean($function_oid);
+
+               $sql = "
+                       SELECT
+                               pc.oid AS prooid, proname, pg_catalog.pg_get_userbyid(proowner) AS proowner,
+                               nspname as proschema, lanname as prolanguage, procost, prorows,
+                               pg_catalog.format_type(prorettype, NULL) as proresult, prosrc,
+                               probin, proretset, proisstrict, provolatile, prosecdef,
+                               pg_catalog.oidvectortypes(pc.proargtypes) AS proarguments,
+                               proargnames AS proargnames,
+                               pg_catalog.obj_description(pc.oid, 'pg_proc') AS procomment,
+                               proconfig
+                       FROM
+                               pg_catalog.pg_proc pc, pg_catalog.pg_language pl,
+                               pg_catalog.pg_namespace pn
+                       WHERE
+                               pc.oid = '{$function_oid}'::oid AND pc.prolang = pl.oid
+                               AND pc.pronamespace = pn.oid
+                       ";
+
+               return $this->selectSet($sql);
+       }
+
+
+       // Capabilities
        function hasQueryKill() { return false; }
        function hasDatabaseCollation() { return false; }
        function hasAlterSequenceStart() { return false; }
index 5aa853c7177339c9b2b32d6ddbf4a6f2d86bbf79..5c8078024dbfc703285804ebf46f0bdc5211affc 100644 (file)
 
                        // Deal with named parameters
                        if ($data->hasNamedParams()) {
-                               $args_arr = explode(', ', $fndata->fields['proarguments']);
+                if ( isset($fndata->fields['proallarguments']) ) {
+                    $args_arr = $data->phpArray($fndata->fields['proallarguments']);
+                } else {
+                                   $args_arr = explode(', ', $fndata->fields['proarguments']);
+                }
                                $names_arr = $data->phpArray($fndata->fields['proargnames']);
+                $modes_arr = $data->phpArray($fndata->fields['proargmodes']);
                                $args = '';
                                $i = 0;
                                for ($i = 0; $i < sizeof($args_arr); $i++) {
                                        if ($i != 0) $args .= ', ';
+                    switch($modes_arr[$i]) {
+                        case 'i' : $args .= " IN "; break;
+                        case 'o' : $args .= " OUT "; break;
+                        case 'b' : $args .= " INOUT "; break;
+                        case 'v' : $args .= " VARIADIC "; break;
+                        case 't' : $args .= " TABLE "; break;
+                    }
                                        if (isset($names_arr[$i]) && $names_arr[$i] != '') {
                                                $data->fieldClean($names_arr[$i]);
                                                $args .= '"' . $names_arr[$i] . '" ';
                if ($funcdata->recordCount() > 0) {
                        // Deal with named parameters
                        if ($data->hasNamedParams()) {
-                               $args_arr = explode(', ', $funcdata->fields['proarguments']);
+                if ( isset($fndata->fields['proallarguments']) ) {
+                    $args_arr = $data->phpArray($funcdata->fields['proallarguments']);
+                } else {
+                                   $args_arr = explode(', ', $funcdata->fields['proarguments']);
+                }
                                $names_arr = $data->phpArray($funcdata->fields['proargnames']);
+                $modes_arr = $data->phpArray($funcdata->fields['proargmodes']);
                                $args = '';
                                $i = 0;
                                for ($i = 0; $i < sizeof($args_arr); $i++) {
                                        if ($i != 0) $args .= ', ';
+                    if (isset($modes_arr[$i])) {
+                        switch($modes_arr[$i]) {
+                            case 'i' : $args .= " IN "; break;
+                            case 'o' : $args .= " OUT "; break;
+                            case 'b' : $args .= " INOUT "; break;
+                            case 'v' : $args .= " VARIADIC "; break;
+                            case 't' : $args .= " TABLE "; break;
+                        }
+                    }
                                        if (isset($names_arr[$i]) && $names_arr[$i] != '') {
                                                $data->fieldClean($names_arr[$i]);
                                                $args .= '"' . $names_arr[$i] . '" ';