diff --git a/pgadmin/schema/edbPackageFunction.cpp b/pgadmin/schema/edbPackageFunction.cpp
index f27070e..8818188 100644
--- a/pgadmin/schema/edbPackageFunction.cpp
+++ b/pgadmin/schema/edbPackageFunction.cpp
@@ -138,9 +138,14 @@ wxString edbPackageFunction::GetArgListWithNames()
 			arg += argTypesArray.Item(i);
 
 		// Parameter default value
-		if (GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) || GetConnection()->BackendMinimumVersion(8, 4))
+		if (GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) &&
+		        !argDefsArray.IsEmpty())
 		{
-			if (!argModesArray.Item(i).IsSameAs(wxT("OUT"), false) && !argDefsArray.Item(i).IsEmpty())
+			if ((argModesArray.Item(i).IsEmpty() ||
+			        argModesArray.Item(i) == wxT("IN") ||
+			        argModesArray.Item(i) == wxT("VARIADIC")) &&
+			        !argDefsArray.Item(i).IsEmpty() &&
+			        i < argDefsArray.Count())
 				arg += wxT(" DEFAULT ") + argDefsArray.Item(i);
 		}
 
@@ -268,8 +273,14 @@ edbPackageFunction *edbPackageFunctionFactory::AppendFunctions(pgObject *obj, ed
 
 	if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS))
 	{
-		argDefsCol = obj->GetConnection()->EdbMinimumVersion(8, 4) ? wxT("proargdefaults") : wxT("proargdefvals");
-		argDefsCol += wxT(" AS argdefaults, ");
+		if (obj->GetConnection()->EdbMinimumVersion(8, 4))
+		{
+			argDefsCol = wxT("pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS argdefaults, pronargdefaults, ");
+		}
+		else
+		{
+			argDefsCol = wxT("proargdefvals AS argdefaults, COALESCE(substring(array_dims(proargdefvals), E'1:(.*)\\]')::integer, 0) AS pronargdefaults, ");
+		}
 	}
 
 	if (obj->GetConnection()->EdbMinimumVersion(8, 2))
@@ -306,6 +317,8 @@ edbPackageFunction *edbPackageFunctionFactory::AppendFunctions(pgObject *obj, ed
 	{
 		while (!packageFunctions->Eof())
 		{
+			size_t inModeCnt = 0;
+			size_t defaultArgsCnt = 0;
 			if (packageFunctions->GetVal(wxT("eltclass")) == wxT("F"))
 				packageFunction = new edbPackageFunction(package, packageFunctions->GetVal(wxT("eltname")));
 			else
@@ -313,7 +326,8 @@ edbPackageFunction *edbPackageFunctionFactory::AppendFunctions(pgObject *obj, ed
 
 			// Tokenize the arguments
 			wxStringTokenizer argTypesTkz(wxEmptyString), argModesTkz(wxEmptyString);
-			queryTokenizer argNamesTkz(wxEmptyString, (wxChar)','),  argDefsTkz(wxEmptyString, (wxChar)',');
+			queryTokenizer argNamesTkz(wxEmptyString, (wxChar)',');
+			wxArrayString argDefValArray;
 			wxString tmp;
 
 			// Types
@@ -340,14 +354,21 @@ edbPackageFunction *edbPackageFunctionFactory::AppendFunctions(pgObject *obj, ed
 			// Function defaults
 			if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS))
 			{
-				tmp = packageFunctions->GetVal(wxT("argdefaults"));
+				defaultArgsCnt = packageFunctions->GetLong(wxT("pronargdefaults"));
 
-				if (!tmp.IsEmpty())
-					argDefsTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(","));
+				if (defaultArgsCnt > 0)
+				{
+					tmp = packageFunctions->GetVal(wxT("argdefaults"));
+
+					if (!tmp.IsEmpty())
+					{
+						getArrayFromCommaSeparatedList(tmp.Mid(1, tmp.Length() - 2), argDefValArray);
+					}
+				}
 			}
 
 			// Now iterate the arguments and build the arrays
-			wxString type, name, mode, def;
+			wxString type, name, mode;
 
 			while (argTypesTkz.HasMoreTokens())
 			{
@@ -381,32 +402,70 @@ edbPackageFunction *edbPackageFunctionFactory::AppendFunctions(pgObject *obj, ed
 							mode = wxT("INOUT");
 					else if (mode == wxT("3"))
 						mode = wxT("IN OUT");
+					else if (mode == wxT("v"))
+					{
+						inModeCnt++;
+						mode = wxT("VARIADIC");
+					}
 					else
+					{
+						inModeCnt++;
 						mode = wxT("IN");
+					}
 
 					packageFunction->iAddArgMode(mode);
 				}
 				else
 					packageFunction->iAddArgMode(wxEmptyString);
+			}
 
-				// Finally the defaults, as we got them.
-				def = argDefsTkz.GetNextToken();
-				if (!def.IsEmpty() && !def.IsSameAs(wxT("-")))
+			// Finally the defaults, as we got them.
+			if (packageFunction->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS))
+			{
+				size_t currINindex = 0;
+				while (inModeCnt)
 				{
-					if (def[0] == '"')
-						def = def.Mid(1, def.Length() - 2);
-
-					// Check the cache first - if we don't have a value, get it and cache for next time
-					wxString val = exprCache[def];
-					if (val == wxEmptyString)
+					for (size_t index = 0; index < packageFunction->GetArgTypesArray().Count(); index++)
 					{
-						val = obj->GetDatabase()->ExecuteScalar(wxT("SELECT pg_get_expr('") + def + wxT("', 'pg_catalog.pg_class'::regclass)"));
-						exprCache[def] = val;
+						wxString def = wxEmptyString;
+						if(packageFunction->GetArgModesArray()[index].IsEmpty() ||
+						        packageFunction->GetArgModesArray()[index] == wxT("IN") ||
+						        packageFunction->GetArgModesArray()[index] == wxT("VARIADIC"))
+						{
+							if (!argDefValArray.IsEmpty() && inModeCnt <= argDefValArray.GetCount())
+							{
+								def = argDefValArray[currINindex++];
+
+								if (!def.IsEmpty() && def != wxT("-"))
+								{
+									// Only EDB 8.3 does not support get the
+									// default value using pg_get_expr directly
+									if (!packageFunction->GetConnection()->BackendMinimumVersion(8, 4))
+									{
+										// Check the cache first - if we don't
+										// have a value, get it and cache for
+										// next time
+										wxString val = exprCache[def];
+
+										if (val == wxEmptyString)
+										{
+											val = obj->GetDatabase()->ExecuteScalar(
+											          wxT("SELECT pg_get_expr('") + def.Mid(1, def.Length() - 2) + wxT("', 'pg_catalog.pg_class'::regclass)"));
+											exprCache[def] = val;
+										}
+										def = val;
+									}
+								}
+								else
+								{
+									def = wxEmptyString;
+								}
+							}
+							inModeCnt--;
+						}
+						packageFunction->iAddArgDef(def);
 					}
-					packageFunction->iAddArgDef(val);
 				}
-				else
-					packageFunction->iAddArgDef(wxEmptyString);
 			}
 
 			packageFunction->iSetOid(packageFunctions->GetOid(wxT("oid")));
diff --git a/pgadmin/schema/pgFunction.cpp b/pgadmin/schema/pgFunction.cpp
index 0e9c087..e07810b 100644
--- a/pgadmin/schema/pgFunction.cpp
+++ b/pgadmin/schema/pgFunction.cpp
@@ -538,10 +538,21 @@ wxString pgFunction::GetArgListWithNames()
 			arg += argTypesArray.Item(i);
 
 		// Parameter default value
-		if (GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) || GetConnection()->BackendMinimumVersion(8, 4))
+		if (GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS)
+		        && !argDefsArray.IsEmpty())
 		{
-			if (!argModesArray.Item(i).IsSameAs(wxT("OUT"), false) && !argDefsArray.Item(i).IsEmpty())
+			if ((argModesArray.Item(i).IsEmpty() ||
+			        argModesArray.Item(i) == wxT("IN") ||
+			        // 'edbspl' does not support default value with
+			        // INOUT parameter
+			        (argModesArray.Item(i) == wxT("INOUT") &&
+			         GetLanguage() != wxT("edbspl")) ||
+			        argModesArray.Item(i) == wxT("VARIADIC")) &&
+			        !argDefsArray.Item(i).IsEmpty() &&
+			        i < argDefsArray.Count())
+			{
 				arg += wxT(" DEFAULT ") + argDefsArray.Item(i);
+			}
 		}
 
 		args += arg;
@@ -607,7 +618,7 @@ pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema,
 	if (obj->GetConnection()->BackendMinimumVersion(8, 0))
 		argNamesCol = wxT("proargnames, ");
 	if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) && !obj->GetConnection()->BackendMinimumVersion(8, 4))
-		argDefsCol = wxT("proargdefvals, ");
+		argDefsCol = wxT("proargdefvals, COALESCE(substring(array_dims(proargdefvals), E'1:(.*)\\]')::integer, 0) AS pronargdefaults, ");
 	if (obj->GetConnection()->BackendMinimumVersion(8, 4))
 		argDefsCol = wxT("pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals, pronargdefaults, ");
 	if (obj->GetConnection()->BackendMinimumVersion(8, 3))
@@ -644,7 +655,6 @@ pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema,
 		while (!functions->Eof())
 		{
 			bool isProcedure = false;
-			bool hasDefValSupport = false;
 			wxString lanname = functions->GetVal(wxT("lanname"));
 			wxString typname = functions->GetVal(wxT("typname"));
 
@@ -669,10 +679,9 @@ pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema,
 
 			// Tokenize the arguments
 			wxStringTokenizer argTypesTkz(wxEmptyString), argModesTkz(wxEmptyString);
-			queryTokenizer argNamesTkz(wxEmptyString, (wxChar)','), argDefsTkz(wxEmptyString, (wxChar)',');
 			wxString tmp;
 
-			// Support for Default Value in PG 8.4
+			wxArrayString argNamesArray;
 			wxArrayString argDefValArray;
 
 			// We always have types
@@ -683,7 +692,7 @@ pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema,
 			{
 				tmp = functions->GetVal(wxT("proargnames"));
 				if (!tmp.IsEmpty())
-					argNamesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(","));
+					getArrayFromCommaSeparatedList(tmp.Mid(1, tmp.Length() - 2), argNamesArray);
 			}
 
 			// EDB 8.0 had modes in pg_proc.proargdirs
@@ -711,12 +720,13 @@ pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema,
 			{
 				tmp = functions->GetVal(wxT("proargdefvals"));
 				if (!tmp.IsEmpty())
-					argDefsTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(","));
+					getArrayFromCommaSeparatedList(tmp.Mid(1, tmp.Length() - 2), argDefValArray);
+
+				function->iSetArgDefValCount(functions->GetLong(wxT("pronargdefaults")));
 			}
 
 			if (obj->GetConnection()->BackendMinimumVersion(8, 4))
 			{
-				hasDefValSupport = true;
 				tmp = functions->GetVal(wxT("proargdefaultvals"));
 				getArrayFromCommaSeparatedList(tmp, argDefValArray);
 
@@ -729,17 +739,22 @@ pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema,
 				function->iSetIsWindow(false);
 
 			// Now iterate the arguments and build the arrays
-			wxString type, name, mode, def;
+			wxString type, name, mode;
 			size_t nArgsIN = 0;
+			size_t nArgNames = 0;
 
 			while (argTypesTkz.HasMoreTokens())
 			{
-
-				// Now add the name, stripping the quotes and \" if
-				// necessary.
-				name = argNamesTkz.GetNextToken();
+				if (nArgNames < argNamesArray.GetCount())
+				{
+					name = argNamesArray[nArgNames++];
+				}
+				else
+					name = wxEmptyString;
 				if (!name.IsEmpty())
 				{
+					// Now add the name, stripping the quotes and \" if
+					// necessary.
 					if (name[0] == '"')
 						name = name.Mid(1, name.Length() - 2);
 					name.Replace(wxT("\\\""), wxT("\""));
@@ -758,9 +773,7 @@ pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema,
 
 							// consume uniformly, mode will definitely be "OUT"
 							mode = argModesTkz.GetNextToken();
-							// no defvals..
-							if (!hasDefValSupport)
-								def = argDefsTkz.GetNextToken();
+
 							continue;
 						}
 					}
@@ -780,18 +793,26 @@ pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema,
 				{
 					if (mode == wxT('o') || mode == wxT("2"))
 						mode = wxT("OUT");
-					else if (mode == wxT("b"))
+					else if (mode == wxT("b") || mode == wxT("3"))
+					{
 						if (isProcedure)
 							mode = wxT("IN OUT");
 						else
 						{
 							mode = wxT("INOUT");
-							nArgsIN++;
+							// 'edbspl' does not support default values for the
+							// INOUT parameters.
+							if (lanname != wxT("edbspl"))
+							{
+								nArgsIN++;
+							}
 						}
-					else if (mode == wxT("3"))
-						mode = wxT("IN OUT");
+					}
 					else if (mode == wxT("v"))
+					{
 						mode = wxT("VARIADIC");
+						nArgsIN++;
+					}
 					else if (mode == wxT("t"))
 						mode = wxT("TABLE");
 					else
@@ -808,69 +829,63 @@ pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema,
 					nArgsIN++;
 				}
 
-				// Finally the defaults, as we got them.
-				if (!hasDefValSupport)
-					def = argDefsTkz.GetNextToken();
-
-				if (hasDefValSupport)
-				{
-					// We will process this later
-				}
-				else if (!def.IsEmpty() && !def.IsSameAs(wxT("-")))
-				{
-					if (def[0] == '"')
-						def = def.Mid(1, def.Length() - 2);
-
-					// Check the cache first - if we don't have a value, get it and cache for next time
-					wxString val = exprCache[def];
-					if (val == wxEmptyString)
-					{
-						val = obj->GetDatabase()->ExecuteScalar(wxT("SELECT pg_get_expr('") + def + wxT("', 'pg_catalog.pg_class'::regclass)"));
-						exprCache[def] = val;
-					}
-					function->iAddArgDef(val);
-				}
-				else
-					function->iAddArgDef(wxEmptyString);
 			}
 
 			function->iSetArgCount(functions->GetLong(wxT("pronargs")));
 
 			wxString strReturnTableArgs;
 			// Process default values
-			if (obj->GetConnection()->BackendMinimumVersion(8, 4))
+			size_t currINindex = 0;
+			for (size_t index = 0; index < function->GetArgModesArray().Count(); index++)
 			{
-				size_t currINindex = 0;
-				for (size_t index = 0; index < function->GetArgModesArray().Count(); index++)
+				wxString def = wxEmptyString;
+				if(function->GetArgModesArray()[index].IsEmpty() ||
+				        function->GetArgModesArray()[index] == wxT("IN") ||
+				        (function->GetArgModesArray()[index] == wxT("INOUT") &&
+				         lanname != wxT("edbspl")) ||
+				        function->GetArgModesArray()[index] == wxT("VARIADIC"))
 				{
-					if (function->GetArgModesArray()[index] == wxT("IN") ||
-					        function->GetArgModesArray()[index] == wxT("INOUT") ||
-					        function->GetArgModesArray()[index].IsEmpty())
+					if (!argDefValArray.IsEmpty() && nArgsIN <= argDefValArray.GetCount())
 					{
-						nArgsIN--;
-						if (function->GetArgDefValCount() != 0 &&
-						        nArgsIN < (size_t)function->GetArgDefValCount())
+						def = argDefValArray[currINindex++];
+						if (!def.IsEmpty() && def != wxT("-"))
 						{
-							if (argDefValArray[currINindex++] != wxT("-"))
-								function->iAddArgDef(argDefValArray[currINindex - 1]);
-							else
-								function->iAddArgDef(wxT(""));
+							// Only EDB 8.3 does not support get the default
+							// value using pg_get_expr directly
+							if (function->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) &&
+							        !function->GetConnection()->BackendMinimumVersion(8, 4))
+							{
+								// Check the cache first - if we don't have a
+								// value, get it and cache for next time
+								wxString val = exprCache[def];
+
+								if (val == wxEmptyString)
+								{
+									val = obj->GetDatabase()->ExecuteScalar(
+									          wxT("SELECT pg_get_expr('") + def.Mid(1, def.Length() - 2) + wxT("', 'pg_catalog.pg_class'::regclass)"));
+									exprCache[def] = val;
+								}
+								def = val;
+							}
 						}
 						else
-							function->iAddArgDef(wxEmptyString);
-					}
-					else if(function->GetArgModesArray()[index] == wxT("TABLE"))
-					{
-						if (strReturnTableArgs.Length() > 0)
-							strReturnTableArgs += wxT(", ");
-						wxString strName = function->GetArgNamesArray()[index];
-						if (!strName.IsEmpty())
-							strReturnTableArgs += qtIdent(strName) + wxT(" ");
-						strReturnTableArgs += function->GetArgTypesArray()[index];
+						{
+							def = wxEmptyString;
+						}
 					}
-					else
-						function->iAddArgDef(wxEmptyString);
+					nArgsIN--;
+				}
+				else if(function->GetConnection()->BackendMinimumVersion(8, 4) &&
+				        function->GetArgModesArray()[index] == wxT("TABLE"))
+				{
+					if (strReturnTableArgs.Length() > 0)
+						strReturnTableArgs += wxT(", ");
+					wxString strName = function->GetArgNamesArray()[index];
+					if (!strName.IsEmpty())
+						strReturnTableArgs += qtIdent(strName) + wxT(" ");
+					strReturnTableArgs += function->GetArgTypesArray()[index];
 				}
+				function->iAddArgDef(def);
 			}
 
 			function->iSetOid(functions->GetOid(wxT("oid")));
