Christopher Browne cbbrowne at ca.afilias.info
Thu Jul 12 13:31:05 PDT 2007
"Dmitry Koterov" <dmitry at koterov.ru> writes:
> The quick & dirty fix for the first one is:
> slony1-1.2.9\src\parsestatements\scanner.c
> if (state == Q_NORMAL_STATE) {
>     state = Q_HOPE_TO_DASH;
>     break;
> }
> replace to
> if (state == Q_NORMAL_STATE && extended_statement[cpos+1] == '-') {
>     state = Q_HOPE_TO_DASH;
>     break;
> }

I was going to object on the basis of "what if we're at the end of the string?"

The string is expected to end with a NULL, so if we've got a dash in
the present position, we can be pretty confident that there will be at
least one more byte in the string.  So I'm OK with that...

I'm not sure what's up with the "folding" of backslashes; the output
from test-scanner seems fine.

Below is the patch, as it stands now...

===================================================================
Index: emptytestresult.expected
===================================================================
RCS file: /home/cvsd/slony1/slony1-engine/src/parsestatements/emptytestresult.expected,v
retrieving revision 1.1
diff -c -u -r1.1 emptytestresult.expected
Binary files /tmp/cvsVpl54F and emptytestresult.expected differ
Index: scanner.c
===================================================================
RCS file: /home/cvsd/slony1/slony1-engine/src/parsestatements/scanner.c,v
retrieving revision 1.3
diff -c -u -r1.3 scanner.c
--- scanner.c	4 Aug 2006 20:40:19 -0000	1.3
+++ scanner.c	12 Jul 2007 20:29:27 -0000
@@ -11,6 +11,9 @@
   char cchar;
   int d1start, d1end, d2start, d2end, d1stemp;
   int statements;
+  int nparens;
+  int nbrokets;
+  int nsquigb;
   
   /* Initialize */
   cpos = 0;
@@ -21,13 +24,49 @@
   d2start = 0;
   d1end = 0;
   state = Q_NORMAL_STATE;
+  nparens = 0;
+  nbrokets = 0;
+  nsquigb = 0;
   
   while (state != Q_DONE) {
     cchar = extended_statement[cpos];
     switch (cchar) {
     case '\0':
+      STMTS[statements++] = ++cpos;
       state = Q_DONE;
       break;
+
+    case '(':
+      if (state == Q_NORMAL_STATE) {
+	nparens ++;
+	break;
+      }
+    case ')':
+      if (state == Q_NORMAL_STATE) {
+	nparens --;
+	break;
+      }
+    case '[':
+      if (state == Q_NORMAL_STATE) {
+	nbrokets ++;
+	break;
+      }
+    case ']':
+      if (state == Q_NORMAL_STATE) {
+	nbrokets --;
+	break;
+      }
+    case '{':
+      if (state == Q_NORMAL_STATE) {
+	nsquigb ++;
+	break;
+      }
+    case '}':
+      if (state == Q_NORMAL_STATE) {
+	nsquigb --;
+	break;
+      }
+
     case '/':
       if (state == Q_NORMAL_STATE) {
 	state = Q_HOPE_TO_CCOMMENT;
@@ -51,8 +90,7 @@
 	  bpos = cpos;
 	  break;
 	}
-      } 
-
+      }
       break;
     case '$':
       if (state == Q_NORMAL_STATE) {
@@ -123,7 +161,7 @@
       }
       break;
     case '-':
-      if (state == Q_NORMAL_STATE) {
+      if (state == Q_NORMAL_STATE && extended_statement[cpos+1] == '-') {
 	state = Q_HOPE_TO_DASH;
 	break;
       }
@@ -151,7 +189,7 @@
       if (state == Q_DOLLAR_UNBUILDING) state = Q_DOLLAR_QUOTING;
       break;
     case ';':
-      if (state == Q_NORMAL_STATE) {
+      if ((state == Q_NORMAL_STATE) && (nparens == 0) && (nbrokets == 0) && (nsquigb == 0)) {
 	STMTS[statements++] = ++cpos;
 	if (statements >= MAXSTATEMENTS) {
 	  return statements;
Index: test_sql.expected
===================================================================
RCS file: /home/cvsd/slony1/slony1-engine/src/parsestatements/test_sql.expected,v
retrieving revision 1.2
diff -c -u -r1.2 test_sql.expected
--- test_sql.expected	24 Feb 2006 18:48:12 -0000	1.2
+++ test_sql.expected	12 Jul 2007 20:29:27 -0000
@@ -37,6 +37,31 @@
 $$ language plpgsql;
 
 
+-- Here is a rule creation with an embedded semicolon
+-- "Dmitry Koterov" <dmitry at koterov.ru>
+
+create table "public"."position";
+
+CREATE RULE "position_get_last_id_on_insert2"
+AS ON INSERT TO "public"."position" DO (SELECT
+currval('position_position_id_seq'::regclass) AS id;);
+
+-- Added to verify handling of queries tried by
+-- "Dmitry Koterov" <dmitry at koterov.ru>
+
+CREATE INDEX aaa ON public.bbb USING btree ((-ccc), ddd);
+
+--  Apparently a pair of backslashes fold down into one?
+-- "Dmitry Koterov" <dmitry at koterov.ru>
+
+CREATE UNIQUE INDEX "i_dictionary_uni_abbr" ON "static"."dictionary"
+USING btree ((substring(dic_russian, E'^([^(]*[^( ]) *\\('::text)))
+WHERE (dic_category_id = 26);
+
+-- Force a query to be at the end...
+
+create table foo;
+
 statement 0
 -------------------------------------------
 select * from foo;
@@ -114,4 +139,48 @@
     select $24$ -- another " " thing ' ' \\\'\$ $24$;
     return NULL;
   end;
-$$ language plpgsql;
\ No newline at end of file
+$$ language plpgsql;
+statement 14
+-------------------------------------------
+
+
+
+-- Here is a rule creation with an embedded semicolon
+-- "Dmitry Koterov" <dmitry at koterov.ru>
+
+create table "public"."position";
+statement 15
+-------------------------------------------
+
+
+CREATE RULE "position_get_last_id_on_insert2"
+AS ON INSERT TO "public"."position" DO (SELECT
+currval('position_position_id_seq'::regclass) AS id;);
+statement 16
+-------------------------------------------
+
+
+-- Added to verify handling of queries tried by
+-- "Dmitry Koterov" <dmitry at koterov.ru>
+
+CREATE INDEX aaa ON public.bbb USING btree ((-ccc), ddd);
+statement 17
+-------------------------------------------
+
+
+--  Apparently a pair of backslashes fold down into one?
+-- "Dmitry Koterov" <dmitry at koterov.ru>
+
+CREATE UNIQUE INDEX "i_dictionary_uni_abbr" ON "static"."dictionary"
+USING btree ((substring(dic_russian, E'^([^(]*[^( ]) *\\('::text)))
+WHERE (dic_category_id = 26);
+statement 18
+-------------------------------------------
+
+
+-- Force a query to be at the end...
+
+create table foo;
+statement 19
+-------------------------------------------
+. 
\ No newline at end of file
Index: test_sql.sql
===================================================================
RCS file: /home/cvsd/slony1/slony1-engine/src/parsestatements/test_sql.sql,v
retrieving revision 1.1
diff -c -u -r1.1 test_sql.sql
--- test_sql.sql	24 Feb 2006 18:33:02 -0000	1.1
+++ test_sql.sql	12 Jul 2007 20:29:27 -0000
@@ -35,3 +35,29 @@
     return NULL;
   end;
 $$ language plpgsql;
+
+
+-- Here is a rule creation with an embedded semicolon
+-- "Dmitry Koterov" <dmitry at koterov.ru>
+
+create table "public"."position";
+
+CREATE RULE "position_get_last_id_on_insert2"
+AS ON INSERT TO "public"."position" DO (SELECT
+currval('position_position_id_seq'::regclass) AS id;);
+
+-- Added to verify handling of queries tried by
+-- "Dmitry Koterov" <dmitry at koterov.ru>
+
+CREATE INDEX aaa ON public.bbb USING btree ((-ccc), ddd);
+
+--  Apparently a pair of backslashes fold down into one?
+-- "Dmitry Koterov" <dmitry at koterov.ru>
+
+CREATE UNIQUE INDEX "i_dictionary_uni_abbr" ON "static"."dictionary"
+USING btree ((substring(dic_russian, E'^([^(]*[^( ]) *\\('::text)))
+WHERE (dic_category_id = 26);
+
+-- Force a query to be at the end...
+
+create table foo;
\ No newline at end of file

-- 
select 'cbbrowne' || '@' || 'ca.afilias.info';
<http://dba2.int.libertyrms.com/>
Christopher Browne
(416) 673-4124 (land)


More information about the Slony1-general mailing list