CVS User Account cvsuser
Fri Jun 2 11:49:09 PDT 2006
Log Message:
-----------
Fixed double quote escaping and \' problems.

Jan

Modified Files:
--------------
    slony1-engine/src/backend:
        slony1_funcs.sql (r1.84 -> r1.85)
    slony1-engine/src/slon:
        remote_worker.c (r1.113 -> r1.114)

-------------- next part --------------
Index: slony1_funcs.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.sql,v
retrieving revision 1.84
retrieving revision 1.85
diff -Lsrc/backend/slony1_funcs.sql -Lsrc/backend/slony1_funcs.sql -u -w -r1.84 -r1.85
--- src/backend/slony1_funcs.sql
+++ src/backend/slony1_funcs.sql
@@ -302,7 +302,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;
@@ -319,84 +319,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
@@ -2700,11 +2686,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;
 
@@ -2714,7 +2700,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;
 
@@ -5080,14 +5066,14 @@
 	v_blacklist alias for $2 ;
 	v_ignore int4[] ;
 	v_reachable_edge_last int4[] ;
-	v_reachable_edge_new int4[] default \'{}\' ;
+	v_reachable_edge_new int4[] default ''{}'' ;
 	v_server record ;
 begin
 	v_reachable_edge_last := array[v_node] ;
 	v_ignore := v_blacklist || array[v_node] ;
 	return next v_node ;
-	while v_reachable_edge_last != \'{}\' loop
-		v_reachable_edge_new := \'{}\' ;
+	while v_reachable_edge_last != ''{}'' loop
+		v_reachable_edge_new := ''{}'' ;
 		for v_server in select pa_server as no_id
 			from @NAMESPACE at .sl_path
 			where pa_client = ANY(v_reachable_edge_last) and pa_server != ALL(v_ignore)
Index: remote_worker.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/remote_worker.c,v
retrieving revision 1.113
retrieving revision 1.114
diff -Lsrc/slon/remote_worker.c -Lsrc/slon/remote_worker.c -u -w -r1.113 -r1.114
--- src/slon/remote_worker.c
+++ src/slon/remote_worker.c
@@ -2776,8 +2776,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, "
@@ -2788,6 +2788,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)
@@ -2931,8 +2932,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, "
@@ -2942,6 +2943,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)
@@ -2993,8 +2995,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, "
@@ -3005,6 +3007,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)
@@ -3605,8 +3608,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 "
@@ -3618,6 +3621,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)
@@ -4273,8 +4277,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 "
@@ -4283,6 +4287,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