From fc3726b4b97f1ad8cf061e4eab3a7d284ffc10a2 Mon Sep 17 00:00:00 2001
From: Hiroshi Inoue <inoue@tpf.co.jp>
Date: Wed, 27 Feb 2002 01:43:24 +0000
Subject: [PATCH] Improve the handling of ODBC escape(a request from Marcelo
 Aceto). Change SQLGetFunctions() to reply not yet implemented ODBC 3.0
 functions precisely.

---
 src/interfaces/odbc/convert.c   | 20 +++++++++++++--
 src/interfaces/odbc/info.c      |  4 ++-
 src/interfaces/odbc/odbcapi30.c | 45 ++++++++++++++++++---------------
 3 files changed, 46 insertions(+), 23 deletions(-)

diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c
index 1f3c89981ee..4291e36c34c 100644
--- a/src/interfaces/odbc/convert.c
+++ b/src/interfaces/odbc/convert.c
@@ -1402,6 +1402,8 @@ copy_statement_with_parameters(StatementClass *stmt)
 			}
 			opos = end - old_statement; /* positioned at the last } */
 			new_statement = stmt->stmt_with_params;
+			if (isalnum(end[1]))
+				CVT_APPEND_CHAR(' ');
 			continue;
 		}
 		/* End of a procedure call */
@@ -2015,7 +2017,7 @@ int inner_convert_escape(const ConnectionClass *conn, const char *value,
 	char valnts[1024], params[1024];
 	char key[33], *end;
 	const char *valptr;
-	UInt4	vlen, prtlen, input_consumed, param_consumed;
+	UInt4	vlen, prtlen, input_consumed, param_consumed, extra_len;
 	Int4	param_pos[16][2];
  
 	valptr = value;
@@ -2042,6 +2044,20 @@ int inner_convert_escape(const ConnectionClass *conn, const char *value,
 	*input_resume = valptr + vlen; /* resume from the last } */
 	mylog("%s: key='%s', val='%s'\n", func, key, valnts);
      
+	extra_len = 0;
+	if (isalnum(result[-1])) /* Avoid the concatenation of the function name with the previous word. Aceto */
+	{
+		if (1 >= maxLen)
+		{
+			mylog("%s %d bytes buffer overflow\n", func, maxLen);
+			return CONVERT_ESCAPE_OVERFLOW;
+		}
+		*result = ' ';
+		result++;
+		*result = '\0';
+		maxLen--;
+		extra_len++;
+	}
 	if (strcmp(key, "d") == 0)
 	{
 		/* Literal; return the escape part adding type cast */
@@ -2185,7 +2201,7 @@ int inner_convert_escape(const ConnectionClass *conn, const char *value,
 	}
      
 	if (count)
-		*count = prtlen;
+		*count = prtlen + extra_len;
 	if (prtlen < 0 || prtlen >= maxLen) /* buffer overflow */
 	{
 		mylog("%s %d bytes buffer overflow\n", func, maxLen);
diff --git a/src/interfaces/odbc/info.c b/src/interfaces/odbc/info.c
index 865c8ac7adf..d4fda3670b6 100644
--- a/src/interfaces/odbc/info.c
+++ b/src/interfaces/odbc/info.c
@@ -9,7 +9,7 @@
  * API functions:	SQLGetInfo, SQLGetTypeInfo, SQLGetFunctions,
  *					SQLTables, SQLColumns, SQLStatistics, SQLSpecialColumns,
  *					SQLPrimaryKeys, SQLForeignKeys,
- *					SQLProcedureColumns(NI), SQLProcedures(NI),
+ *					SQLProcedureColumns(NI), SQLProcedures,
  *					SQLTablePrivileges(NI), SQLColumnPrivileges(NI)
  *
  * Comments:		See "notice.txt" for copyright and license information.
@@ -3783,6 +3783,8 @@ PGAPI_TablePrivileges(
 	extend_bindings(stmt, result_cols);
 
 	/* set the field names */
+	stmt->manual_result = TRUE;
+	stmt->result = QR_Constructor();
 	QR_set_num_fields(stmt->result, result_cols);
 	QR_set_field_info(stmt->result, 0, "TABLE_CAT", PG_TYPE_TEXT, MAX_INFO_STRING);
 	QR_set_field_info(stmt->result, 1, "TABLE_SCHEM", PG_TYPE_TEXT, MAX_INFO_STRING);
diff --git a/src/interfaces/odbc/odbcapi30.c b/src/interfaces/odbc/odbcapi30.c
index 1d5a623f74a..2c5e73bf359 100644
--- a/src/interfaces/odbc/odbcapi30.c
+++ b/src/interfaces/odbc/odbcapi30.c
@@ -704,6 +704,9 @@ SQLSetStmtAttr(HSTMT StatementHandle,
 RETCODE		SQL_API
 PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
 {
+	ConnectionClass *conn = (ConnectionClass *) hdbc;
+	ConnInfo	*ci = &(conn->connInfo);
+
 	if (fFunction != SQL_API_ODBC3_ALL_FUNCTIONS)
 		return SQL_ERROR;
 	memset(pfExists, 0, sizeof(UWORD) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
@@ -761,7 +764,8 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLSTATISTICS);		/* 53 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLES); /* 54 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLBROWSECONNECT);	/* 55 */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES);		/* 56 */
+	if (ci->drivers.lie)
+		SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES); /* 56 not implmented yet */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLDATASOURCES);	/* 57 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBEPARAM);	/* 58 */
 	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLEXTENDEDFETCH); 59 deprecated */
@@ -776,41 +780,42 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMPARAMS);		/* 63 */
 	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMOPTIONS); 64 deprecated */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLPRIMARYKEYS);	/* 65 */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURECOLUMNS);		/* 66 */
+	if (ci->drivers.lie)
+		SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURECOLUMNS); /* 66 not implmented yet */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURES);		/* 67 */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPOS); /* 68 */
+	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPOS);		/* 68 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSCROLLOPTIONS);		/* 69 deprecated */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES);		/* 70 */
+	if (ci->drivers.lie)
+		SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES); /* 70 not implemented yet */
 	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERS); */	/* 71 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAMETER);	/* 72 */
 
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCHANDLE);	/* 1001 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAM);		/* 1002 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLCLOSECURSOR);	/* 1003 */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLCOPYDESC);		/* 1004 not implemented
-														 * yet */
+	if (ci->drivers.lie)
+		SQL_FUNC_ESET(pfExists, SQL_API_SQLCOPYDESC); /* 1004 not implemented yet */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLENDTRAN);		/* 1005 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEHANDLE);		/* 1006 */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTATTR); /* 1007 */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCFIELD);	/* 1008 not implemented
-														 * yet */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCREC);		/* 1009 not implemented
-														 * yet */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGFIELD);	/* 1010 not implemented
-														 * yet */
+	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTATTR);	/* 1007 */
+	if (ci->drivers.lie)
+	{
+		SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCFIELD); /* 1008 not implemented yet */
+		SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCREC);	/* 1009 not implemented yet */
+		SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGFIELD); /* 1010 not implemented yet */
+	}
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGREC);		/* 1011 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETENVATTR);		/* 1012 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTATTR);	/* 1014 */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTATTR); /* 1016 */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCFIELD);	/* 1017 not implemeted
-														 * yet */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCREC);		/* 1018 not implemented
-														 * yet */
+	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTATTR);	/* 1016 */
+	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCFIELD);	/* 1017 */
+	if (ci->drivers.lie)
+		SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCREC);	/* 1018 not implemented yet */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETENVATTR);		/* 1019 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTATTR);	/* 1020 */
 	SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCHSCROLL);	/* 1021 */
-	SQL_FUNC_ESET(pfExists, SQL_API_SQLBULKOPERATIONS); /* 24 not implemented
-														 * yet */
+	if (ci->drivers.lie)
+		SQL_FUNC_ESET(pfExists, SQL_API_SQLBULKOPERATIONS); /* 24 not implemented yet */
 
 	return SQL_SUCCESS;
 }
-- 
GitLab