Attached are diffs (against HEAD; should work as well against 1.2) for a hopeful resolution to two problems with the parser that splits apart EXECUTE SCRIPT requests.

http://lists.slony.info/pipermail/slony1-general/2007-January/005659.html
- This reports a problem where a statement is lost if it doesn't end in a semicolon

http://lists.slony.info/pipermail/slony1-general/2007-July/006290.html
- This reports a problem where a statement which has an embedded semicolon gets terminated at that semicolon
? emptytestresult.log
? test-scanner
? test_sql.log
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/cvss0kxvq 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   6 Jul 2007 16:05:02 -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) {
@@ -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
Binary files /tmp/cvs9FnuYZ and test_sql.expected differ
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        6 Jul 2007 16:05:02 -0000
@@ -35,3 +35,13 @@
     return NULL;
   end;
 $$ language plpgsql;
+
+
+-- Here is a rule creation with an embedded semicolon
+
+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;)
+
_______________________________________________
Slony1-general mailing list
[email protected]
http://gborg.postgresql.org/mailman/listinfo/slony1-general

Reply via email to