diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c
index 24906e10ff4cdebc14a6cf38c20a72ef8ed97383..f87b91577997816489aa552a94e435eee1093159 100644
--- a/src/interfaces/odbc/convert.c
+++ b/src/interfaces/odbc/convert.c
@@ -58,19 +58,76 @@ typedef signed char SCHAR;
 
 extern GLOBAL_VALUES globals;
 
-/*	How to map ODBC scalar functions {fn func(args)} to Postgres */
-/*	This is just a simple substitution */
-char *mapFuncs[][2] = {   
-	{ "CONCAT",      "textcat" },
-	{ "LCASE",       "lower"   },
-	{ "LOCATE",      "strpos"  },
-	{ "LENGTH",      "textlen" },
-	{ "LTRIM",       "ltrim"   },
-	{ "RTRIM",       "rtrim"   },
-	{ "SUBSTRING",   "substr"  },
-	{ "UCASE",       "upper"   },
-	{ "NOW",         "now"     },
-	{    0,             0      }
+/*	How to map ODBC scalar functions {fn func(args)} to Postgres
+ *	This is just a simple substitution
+ *	List augmented from
+ *	 http://www.merant.com/datadirect/download/docs/odbc16/Odbcref/rappc.htm
+ * - thomas 2000-04-03
+ */
+char *mapFuncs[][2] = {
+//	{ "ASCII",       "ascii"      },
+	{ "CHAR",        "ichar"      },
+	{ "CONCAT",      "textcat"    },
+//	{ "DIFFERENCE",  "difference" },
+//	{ "INSERT",      "insert"     },
+	{ "LCASE",       "lower"      },
+	{ "LEFT",        "ltrunc"     },
+	{ "LOCATE",      "strpos"     },
+	{ "LENGTH",      "char_length"},
+//	{ "LTRIM",       "ltrim"      },
+	{ "RIGHT",       "rtrunc"     },
+//	{ "REPEAT",      "repeat"     },
+//	{ "REPLACE",     "replace"    },
+//	{ "RTRIM",       "rtrim"      },
+//	{ "SOUNDEX",     "soundex"    },
+	{ "SUBSTRING",   "substr"     },
+	{ "UCASE",       "upper"      },
+
+//	{ "ABS",         "abs"        },
+//	{ "ACOS",        "acos"       },
+//	{ "ASIN",        "asin"       },
+//	{ "ATAN",        "atan"       },
+//	{ "ATAN2",       "atan2"      },
+	{ "CEILING",     "ceil"       },
+//	{ "COS",         "cos"        },
+//	{ "COT",         "cot"        },
+//	{ "DEGREES",     "degrees"    },
+//	{ "EXP",         "exp"        },
+//	{ "FLOOR",       "floor"      },
+	{ "LOG",         "ln"         },
+	{ "LOG10",       "log"        },
+//	{ "MOD",         "mod"        },
+//	{ "PI",          "pi"         },
+	{ "POWER",       "pow"        },
+//	{ "RADIANS",     "radians"    },
+	{ "RAND",        "random"     },
+//	{ "ROUND",       "round"      },
+//	{ "SIGN",        "sign"       },
+//	{ "SIN",         "sin"        },
+//	{ "SQRT",        "sqrt"       },
+//	{ "TAN",         "tan"        },
+//	{ "TRUNCATE",    "truncate"   },
+
+//	{ "CURDATE",     "curdate"    },
+//	{ "CURTIME",     "curtime"    },
+//	{ "DAYNAME",     "dayname"    },
+//	{ "DAYOFMONTH",  "dayofmonth" },
+//	{ "DAYOFWEEK",   "dayofweek"  },
+//	{ "DAYOFYEAR",   "dayofyear"  },
+//	{ "HOUR",        "hour"       },
+//	{ "MINUTE",      "minute"     },
+//	{ "MONTH",       "month"      },
+//	{ "MONTHNAME",   "monthname"  },
+//	{ "NOW",         "now"        },
+//	{ "QUARTER",     "quarter"    },
+//	{ "SECOND",      "second"     },
+//	{ "WEEK",        "week"       },
+//	{ "YEAR",        "year"       },
+
+//	{ "DATABASE",    "database"   },
+	{ "IFNULL",      "coalesce"   },
+	{ "USER",        "odbc_user"  },
+	{    0,             0         }
 };
 
 char *mapFunction(char *func);
@@ -584,7 +641,7 @@ int
 copy_statement_with_parameters(StatementClass *stmt)
 {
 static char *func="copy_statement_with_parameters";
-unsigned int opos, npos;
+unsigned int opos, npos, oldstmtlen;
 char param_string[128], tmp[256], cbuf[TEXT_FIELD_SIZE+5];
 int param_number;
 Int2 param_ctype, param_sqltype;
@@ -629,14 +686,17 @@ int lobj_fd, retval;
 
     param_number = -1;
 
-    for (opos = 0; opos < strlen(old_statement); opos++) {
+	oldstmtlen = strlen(old_statement);
+
+    for (opos = 0; opos <  oldstmtlen; opos++) {
 
 		//	Squeeze carriage-returns/linfeed pairs to linefeed only
-		if (old_statement[opos] == '\r' && opos+1<strlen(old_statement) && old_statement[opos+1] == '\n') {
+		if (old_statement[opos] == '\r' && opos+1 < oldstmtlen &&
+			old_statement[opos+1] == '\n') {
 			continue;
 		}
 
-		//	Handle literals (date, time, timestamp)
+		//	Handle literals (date, time, timestamp) and ODBC scalar functions
 		else if (old_statement[opos] == '{') {
 			char *esc;
 			char *begin = &old_statement[opos + 1];
@@ -1056,37 +1116,69 @@ int i;
 	return NULL;
 }
 
-//	This function returns a pointer to static memory!
+/* convert_escape()
+ * This function returns a pointer to static memory!
+ */
 char *
 convert_escape(char *value)
 {
-char key[32], val[256];
 static char escape[1024];
-char func[32], the_rest[1024];
-char *mapFunc;
-
-	sscanf(value, "%s %[^\r]", key, val);
+char key[33];
 
-	mylog("convert_escape: key='%s', val='%s'\n", key, val);
+	/* Separate off the key, skipping leading and trailing whitespace */
+	while ((*value != '\0') && isspace(*value)) value++;
+	sscanf(value, "%32s", key);
+	while ((*value != '\0') && (! isspace(*value))) value++;
+	while ((*value != '\0') && isspace(*value)) value++;
 
-	if ( ! strcmp(key, "d") ||
-		 ! strcmp(key, "t") ||
-		 ! strcmp(key, "ts")) {
+	mylog("convert_escape: key='%s', val='%s'\n", key, value);
 
-		strcpy(escape, val);
+	if ( (strcmp(key, "d") == 0) ||
+		 (strcmp(key, "t") == 0) ||
+		 (strcmp(key, "ts") == 0)) {
+		/* Literal; return the escape part as-is */
+		strncpy(escape, value, sizeof(escape)-1);
 	}
-	else if ( ! strcmp(key, "fn")) {
-		sscanf(val, "%[^(]%[^\r]", func, the_rest);
-		mapFunc = mapFunction(func);
-		if ( ! mapFunc)
-			return NULL;
-		else {
-			strcpy(escape, mapFunc);
-			strcat(escape, the_rest);
+	else if (strcmp(key, "fn") == 0) {
+		/* Function invocation
+		 * Separate off the func name,
+		 * skipping trailing whitespace.
+		 */
+		char *funcEnd = value;
+		char svchar;
+		char *mapFunc;
+
+		while ((*funcEnd != '\0') && (*funcEnd != '(') &&
+			   (! isspace(*funcEnd))) funcEnd++;
+		svchar = *funcEnd;
+		*funcEnd = '\0';
+		sscanf(value, "%32s", key);
+		*funcEnd = svchar;
+		while ((*funcEnd != '\0') && isspace(*funcEnd)) funcEnd++;
+
+		/* We expect left parenthensis here,
+		 * else return fn body as-is since it is
+		 * one of those "function constants".
+		 */
+		if (*funcEnd != '(') {
+			strncpy(escape, value, sizeof(escape)-1);
+			return escape;
 		}
-
+		mapFunc = mapFunction(key);
+		/* We could have mapFunction() return key if not in table...
+		 * - thomas 2000-04-03
+		 */
+		if (mapFunc == NULL) {
+			/* If unrecognized function name, return fn body as-is */
+			strncpy(escape, value, sizeof(escape)-1);
+			return escape;
+		}
+		/* copy mapped name and remaining input string */
+		strcpy(escape, mapFunc);
+		strncat(escape, funcEnd, sizeof(escape)-strlen(mapFunc));
 	}
 	else {
+		/* Bogus key, leave untranslated */
 		return NULL;
 	}