CVS User Account cvsuser
Fri Jun 2 10:28:53 PDT 2006
Log Message:
-----------
Fixed escaping of double quotes in identifiers.

Tags:
----
REL_1_1_STABLE

Modified Files:
--------------
    slony1-engine/src/backend:
        slony1_funcs.sql (r1.64.2.16 -> r1.64.2.17)
    slony1-engine/src/slon:
        remote_worker.c (r1.86.2.12 -> r1.86.2.13)

-------------- next part --------------
Index: slony1_funcs.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.sql,v
retrieving revision 1.64.2.16
retrieving revision 1.64.2.17
diff -Lsrc/backend/slony1_funcs.sql -Lsrc/backend/slony1_funcs.sql -u -w -r1.64.2.16 -r1.64.2.17
--- src/backend/slony1_funcs.sql
+++ src/backend/slony1_funcs.sql
@@ -287,7 +287,7 @@
     p_tab_fqname alias for $1;
     v_fqname text default '''';
 begin
-    v_fqname := ''"'' || replace(p_tab_fqname,''\"'',''\\\\"'') || ''"'';
+    v_fqname := ''"'' || replace(p_tab_fqname,''"'',''""'') || ''"'';
     return v_fqname;
 end;
 ' language plpgsql;
@@ -304,84 +304,70 @@
 --
 --	This function will be used to quote user input.
 -- ----------------------------------------------------------------------
-
---create or replace function @NAMESPACE at .slon_quote_input (text) returns text
---as '
---declare
---    p_tab_fqname alias for $1;
---    v_temp_fqname text default '''';
---    v_pre_quoted text[] default ''{}'';
---    v_pre_quote_counter smallint default 0;
---    v_count_fqname smallint default 0;
---    v_fqname_split text[];
---    v_quoted_fqname text default '''';
---begin
---    v_temp_fqname := p_tab_fqname;
-
---    LOOP
---	v_pre_quote_counter := v_pre_quote_counter + 1;
---	v_pre_quoted[v_pre_quote_counter] := 
---	    substring(v_temp_fqname from ''%#"\"%\"#"%'' for ''#'');
---	IF v_pre_quoted[v_pre_quote_counter] <> '''' THEN
---	    v_temp_fqname := replace(v_temp_fqname,
---	        v_pre_quoted[v_pre_quote_counter], ''@'' ||
---		v_pre_quote_counter);
---	ELSE
---	    EXIT;
---	END IF;
---    END LOOP;
-
---    v_fqname_split := string_to_array(v_temp_fqname , ''.'');
---    v_count_fqname := array_upper (v_fqname_split, 1);
-
---    FOR i in 1..v_count_fqname LOOP
---        IF substring(v_fqname_split[i],1,1) = ''@'' THEN
---            v_quoted_fqname := v_quoted_fqname || 
---		v_pre_quoted[substring (v_fqname_split[i] from 2)::int];
---        ELSE
---            v_quoted_fqname := v_quoted_fqname || ''"'' || 
---		v_fqname_split[i] || ''"'';
---        END IF;
-
---        IF i < v_count_fqname THEN
---            v_quoted_fqname := v_quoted_fqname || ''.'' ;
---        END IF;
---    END LOOP;
-	
---    return v_quoted_fqname;
---end;
---' language plpgsql;
-
-
 create or replace function @NAMESPACE at .slon_quote_input(text) returns text as '
   declare
      p_tab_fqname alias for $1;
      v_nsp_name text;
      v_tab_name text;
+	 v_i integer;
+	 v_l integer;
      v_pq2 integer;
 begin
-  if (p_tab_fqname like ''"%"."%"'') then
-    v_pq2 := position (''"'' in substr(p_tab_fqname, 2));
-    v_nsp_name := substr(p_tab_fqname, 2, v_pq2 - 1);
-    v_tab_name := substr(p_tab_fqname, v_pq2 + 4, length(p_tab_fqname) - (v_pq2 + 4));
-  elsif (p_tab_fqname like ''"%".%'') then
-    v_pq2 := position (''"'' in substr(p_tab_fqname, 2));
-    v_nsp_name := substr(p_tab_fqname, 2, v_pq2 - 1);
-    v_tab_name := substr(p_tab_fqname, v_pq2 + 3, length(p_tab_fqname) - (v_pq2 + 2));
-  elsif (p_tab_fqname like ''%."%"'') then
-    v_pq2 := position (''.'' in substr(p_tab_fqname, 2));
-    v_nsp_name := substr(p_tab_fqname, 1, v_pq2);
-    v_tab_name := substr(p_tab_fqname, v_pq2 + 3, length(p_tab_fqname) - (v_pq2 + 3));
-  elsif (p_tab_fqname like ''%.%'') then
-    v_pq2 := position (''.'' in substr(p_tab_fqname, 2));
-    v_nsp_name := substr(p_tab_fqname, 1, v_pq2);
-    v_tab_name := substr(p_tab_fqname, v_pq2 + 2);
-  elsif (p_tab_fqname like ''"%"'') then
+	v_l := length(p_tab_fqname);
+
+	-- Let us search for the dot
+	if p_tab_fqname like ''"%'' then
+		-- if the first part of the ident starts with a double quote, search
+		-- for the closing double quote, skipping over double double quotes.
+		v_i := 2;
+		while v_i <= v_l loop
+			if substr(p_tab_fqname, v_i, 1) != ''"'' then
+				v_i := v_i + 1;
+				continue;
+			end if;
+			v_i := v_i + 1;
+			if substr(p_tab_fqname, v_i, 1) != ''"'' then
+				exit;
+			end if;
+			v_i := v_i + 1;
+		end loop;
+	else
+		-- first part of ident is not quoted, search for the dot directly
+		v_i := 1;
+		while v_i <= v_l loop
+			if substr(p_tab_fqname, v_i, 1) = ''.'' then
+				exit;
+			end if;
+			v_i := v_i + 1;
+		end loop;
+	end if;
+
+	-- v_i now points at the dot or behind the string.
+
+	if substr(p_tab_fqname, v_i, 1) = ''.'' then
+		-- There is a dot now, so split the ident into its namespace
+		-- and objname parts and make sure each is quoted
+		v_nsp_name := substr(p_tab_fqname, 1, v_i - 1);
+		v_tab_name := substr(p_tab_fqname, v_i + 1);
+		if v_nsp_name not like ''"%'' then
+			v_nsp_name := ''"'' || replace(v_nsp_name, ''"'', ''""'') ||
+						  ''"'';
+		end if;
+		if v_tab_name not like ''"%'' then
+			v_tab_name := ''"'' || replace(v_tab_name, ''"'', ''""'') ||
+						  ''"'';
+		end if;
+
+		return v_nsp_name || ''.'' || v_tab_name;
+	else
+		-- No dot ... must be just an ident without schema
+		if p_tab_fqname like ''"%'' then
     return p_tab_fqname;
   else
-     return ''"'' || p_tab_fqname || ''"'';
+			return ''"'' || replace(p_tab_fqname, ''"'', ''""'') || ''"'';
+		end if;
   end if;
-  return ''"'' || v_nsp_name || ''"."'' || v_tab_name || ''"'';
+
 end;' language plpgsql;
 
 comment on function @NAMESPACE at .slon_quote_input(text) is
@@ -2515,11 +2501,11 @@
 			and @NAMESPACE at .slon_quote_input(p_fqname) = @NAMESPACE at .slon_quote_brute(PGN.nspname) ||
 					''.'' || @NAMESPACE at .slon_quote_brute(PGC.relname);
 	if not found then
-		raise exception ''Slony-I: setAddTable(): table % not found'', 
+		raise exception ''Slony-I: setAddTable_int(): table % not found'', 
 				p_fqname;
 	end if;
 	if v_relkind != ''r'' then
-		raise exception ''Slony-I: setAddTable(): % is not a regular table'',
+		raise exception ''Slony-I: setAddTable_int(): % is not a regular table'',
 				p_fqname;
 	end if;
 
@@ -2529,7 +2515,7 @@
 				and PGX.indexrelid = PGC.oid
 				and PGC.relname = p_tab_idxname)
 	then
-		raise exception ''Slony-I: setAddTable(): table % has no index %'',
+		raise exception ''Slony-I: setAddTable_int(): table % has no index %'',
 				p_fqname, p_tab_idxname;
 	end if;
 
Index: remote_worker.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/remote_worker.c,v
retrieving revision 1.86.2.12
retrieving revision 1.86.2.13
diff -Lsrc/slon/remote_worker.c -Lsrc/slon/remote_worker.c -u -w -r1.86.2.12 -r1.86.2.13
--- src/slon/remote_worker.c
+++ src/slon/remote_worker.c
@@ -2402,8 +2402,8 @@
 	 */
 	slon_mkquery(&query1,
 		     "select T.tab_id, "
-		     "    %s.slon_quote_input('\"' || PGN.nspname || '\".\"' || "
-		     "    PGC.relname || '\"') as tab_fqname, "
+		     "    %s.slon_quote_brute(PGN.nspname) || '.' || "
+		     "    %s.slon_quote_brute(PGC.relname) as tab_fqname, "
 		     "    T.tab_idxname, T.tab_comment "
 		     "from %s.sl_table T, "
 		     "    \"pg_catalog\".pg_class PGC, "
@@ -2414,6 +2414,7 @@
 		     "order by tab_id; ",
 		     rtcfg_namespace, 
 		     rtcfg_namespace, 
+		     rtcfg_namespace, 
 		     set_id);
 	res1 = PQexec(pro_dbconn, dstring_data(&query1));
 	if (PQresultStatus(res1) != PGRES_TUPLES_OK)
@@ -2535,8 +2536,8 @@
 	 */
 	slon_mkquery(&query1,
 		     "select SQ.seq_id, "
-		     "    %s.slon_quote_input('\"' || PGN.nspname || '\".\"' || "
-		     "    PGC.relname || '\"') as tab_fqname, "
+		     "    %s.slon_quote_brute(PGN.nspname) || '.' || "
+		     "    %s.slon_quote_brute(PGC.relname) as tab_fqname, "
 		     "		SQ.seq_comment "
 		     "	from %s.sl_sequence SQ, "
 		     "		\"pg_catalog\".pg_class PGC, "
@@ -2546,6 +2547,7 @@
 		     "		and PGN.oid = PGC.relnamespace; ",
 		     rtcfg_namespace, 
 		     rtcfg_namespace, 
+		     rtcfg_namespace, 
 		     set_id);
 	res1 = PQexec(pro_dbconn, dstring_data(&query1));
 	if (PQresultStatus(res1) != PGRES_TUPLES_OK)
@@ -2597,8 +2599,8 @@
 	 */
 	slon_mkquery(&query1,
 		     "select T.tab_id, "
-		     "    %s.slon_quote_input('\"' || PGN.nspname || '\".\"' || "
-		     "    PGC.relname || '\"') as tab_fqname, "
+		     "    %s.slon_quote_brute(PGN.nspname) || '.' || "
+		     "    %s.slon_quote_brute(PGC.relname) as tab_fqname, "
 		     "    T.tab_idxname, T.tab_comment "
 		     "from %s.sl_table T, "
 		     "    \"pg_catalog\".pg_class PGC, "
@@ -2609,6 +2611,7 @@
 		     "order by tab_id; ",
 		     rtcfg_namespace, 
 		     rtcfg_namespace, 
+		     rtcfg_namespace, 
 		     set_id);
 	res1 = PQexec(pro_dbconn, dstring_data(&query1));
 	if (PQresultStatus(res1) != PGRES_TUPLES_OK)
@@ -3194,8 +3197,8 @@
 	 */
 	slon_mkquery(&query1,
 		     "select SL.seql_seqid, SL.seql_last_value, "
-		     "    %s.slon_quote_input('\"' || PGN.nspname || '\".\"' || "
-		     "    PGC.relname || '\"') as tab_fqname "
+		     "    %s.slon_quote_brute(PGN.nspname) || '.' || "
+		     "    %s.slon_quote_brute(PGC.relname) as tab_fqname "
 		     "	from %s.sl_sequence SQ, %s.sl_seqlog SL, "
 		     "		\"pg_catalog\".pg_class PGC, "
 		     "		\"pg_catalog\".pg_namespace PGN "
@@ -3207,6 +3210,7 @@
 		     rtcfg_namespace, 
 		     rtcfg_namespace, 
 		     rtcfg_namespace,
+		     rtcfg_namespace,
 		     set_id, seqbuf);
 	res1 = PQexec(pro_dbconn, dstring_data(&query1));
 	if (PQresultStatus(res1) != PGRES_TUPLES_OK)
@@ -3846,8 +3850,8 @@
 			 */
 			slon_mkquery(&query,
 				     "select T.tab_id, T.tab_set, "
-				     "    %s.slon_quote_input('\"' || PGN.nspname || '\".\"' || "
-				     "    PGC.relname || '\"') as tab_fqname "
+				     "    %s.slon_quote_brute(PGN.nspname) || '.' || "
+				     "    %s.slon_quote_brute(PGC.relname) as tab_fqname "
 				     "from %s.sl_table T, "
 				     "    \"pg_catalog\".pg_class PGC, "
 				     "    \"pg_catalog\".pg_namespace PGN "
@@ -3856,6 +3860,7 @@
 				     "    and PGC.relnamespace = PGN.oid; ",
 				     rtcfg_namespace, 
 				     rtcfg_namespace, 
+				     rtcfg_namespace, 
 				     sub_set);
 			res2 = PQexec(local_dbconn, dstring_data(&query));
 			if (PQresultStatus(res2) != PGRES_TUPLES_OK)



More information about the Slony1-commit mailing list