From 64a2e1fdef195aab773aaa8c92c9aa49e1c5fb12 Mon Sep 17 00:00:00 2001
From: Joe Conway <mail@joeconway.com>
Date: Tue, 24 Feb 2004 05:25:36 +0000
Subject: [PATCH] Apply quote_literal to the start_with argument of connectby.
 Fixes problem reported by David Garamond when working with bytea parent and
 child keys.

---
 contrib/tablefunc/tablefunc.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/contrib/tablefunc/tablefunc.c b/contrib/tablefunc/tablefunc.c
index 74f20c5061c..622164b91b5 100644
--- a/contrib/tablefunc/tablefunc.c
+++ b/contrib/tablefunc/tablefunc.c
@@ -79,6 +79,7 @@ static Tuplestorestate *build_tuplestore_recursively(char *key_fld,
 							 MemoryContext per_query_ctx,
 							 AttInMetadata *attinmeta,
 							 Tuplestorestate *tupstore);
+static char *quote_literal_cstr(char *rawstr);
 
 typedef struct
 {
@@ -1319,23 +1320,23 @@ build_tuplestore_recursively(char *key_fld,
 	/* Build initial sql statement */
 	if (!show_serial)
 	{
-		appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL AND %s <> %s",
+		appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = %s AND %s IS NOT NULL AND %s <> %s",
 						 key_fld,
 						 parent_key_fld,
 						 relname,
 						 parent_key_fld,
-						 start_with,
+						 quote_literal_cstr(start_with),
 						 key_fld, key_fld, parent_key_fld);
 		serial_column = 0;
 	}
 	else
 	{
-		appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = '%s' AND %s IS NOT NULL AND %s <> %s ORDER BY %s",
+		appendStringInfo(sql, "SELECT %s, %s FROM %s WHERE %s = %s AND %s IS NOT NULL AND %s <> %s ORDER BY %s",
 						 key_fld,
 						 parent_key_fld,
 						 relname,
 						 parent_key_fld,
-						 start_with,
+						 quote_literal_cstr(start_with),
 						 key_fld, key_fld, parent_key_fld,
 						 orderby_fld);
 		serial_column = 1;
@@ -1691,3 +1692,21 @@ make_crosstab_tupledesc(TupleDesc spi_tupdesc, int num_categories)
 
 	return tupdesc;
 }
+
+/*
+ * Return a properly quoted literal value.
+ * Uses quote_literal in quote.c
+ */
+static char *
+quote_literal_cstr(char *rawstr)
+{
+	text	   *rawstr_text;
+	text	   *result_text;
+	char	   *result;
+
+	rawstr_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(rawstr)));
+	result_text = DatumGetTextP(DirectFunctionCall1(quote_literal, PointerGetDatum(rawstr_text)));
+	result = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(result_text)));
+
+	return result;
+}
-- 
GitLab