Hi all,

I'm attaching a patch which fixes the corruption in strings caused
by escape processing in the SQL statement. I've tested this for a
while now and it appears to work well. Previously string data 
with {d was getting corrupt as the {d was being stripped regardless
of whether it was an escape code or not.

I also added checking for time and timestamp escape processing strings
as per 11.3 in the specification. The patch is against the latest
CVS.

Cheers,

Tom.
Index: org/postgresql/Statement.java
===================================================================
RCS file: 
/home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Statement.java,v
retrieving revision 1.2
diff -c -r1.2 Statement.java
*** org/postgresql/Statement.java       2001/08/10 14:42:07     1.2
--- org/postgresql/Statement.java       2001/09/10 08:16:48
***************
*** 39,44 ****
--- 39,49 ----
  
      protected boolean escapeProcessing = true;
  
+     // Static variables for parsing SQL when escapeProcessing is true.
+     private static final short IN_SQLCODE = 0;
+     private static final short IN_STRING = 1;
+     private static final short BACKSLASH =2;
+     private static final short ESC_TIMEDATE = 3;
  
      public Statement() {
      }
***************
*** 226,251 ****
      }
  
      /**
!      * This is an attempt to implement SQL Escape clauses
!      */
!     protected static String escapeSQL(String sql) {
!       // If we find a "{d", assume we have a date escape.
!       //
!       // Since the date escape syntax is very close to the
!       // native Postgres date format, we just remove the escape
!       // delimiters.
!       //
!       // This implementation could use some optimization, but it has
!       // worked in practice for two years of solid use.
!       int index = sql.indexOf("{d");
!       while (index != -1) {
!         StringBuffer buf = new StringBuffer(sql);
!         buf.setCharAt(index, ' ');
!         buf.setCharAt(index + 1, ' ');
!         buf.setCharAt(sql.indexOf('}', index), ' ');
!         sql = new String(buf);
!         index = sql.indexOf("{d");
!       }
!       return sql;
      }
  }
--- 231,306 ----
      }
  
      /**
!      * Filter the SQL string of Java SQL Escape clauses. 
!      *
!      * Currently implemented Escape clauses are those mentioned in 11.3
!      * in the specification. Basically we look through the sql string for
!      * {d xxx}, {t xxx} or {ts xxx} in non-string sql code. When we find
!      * them, we just strip the escape part leaving only the xxx part.
!      * So, something like "select * from x where d={d '2001-10-09'}" would
!      * return "select * from x where d= '2001-10-09'".
!      */
!     protected static String escapeSQL(String sql)
!     {
!         // Since escape codes can only appear in SQL CODE, we keep track
!         // of if we enter a string or not.
!         StringBuffer newsql = new StringBuffer();
!         short state = IN_SQLCODE;
! 
!         int i = -1;
!         int len = sql.length();
!         while(++i < len)
!         {
!             char c = sql.charAt(i);
!             switch(state)
!             {
!             case IN_SQLCODE:
!                 if(c == '\'')                // start of a string?
!                     state = IN_STRING;
!                 else if(c == '{')            // start of an escape code?
!                     if(i+1 < len)
!                     {
!                         char next = sql.charAt(i+1);
!                         if(next == 'd')
!                         {
!                             state = ESC_TIMEDATE;
!                             i++;
!                             break;
!                         }
!                         else if(next == 't')
!                         {
!                             state = ESC_TIMEDATE;
!                             i += (i+2 < len && sql.charAt(i+2) == 's') ? 2 : 1;
!                             break;
!                         }
!                     }
!                 newsql.append(c);
!                 break;
! 
!             case IN_STRING:
!                 if(c == '\'')                 // end of string?
!                     state = IN_SQLCODE;
!                 else if(c == '\\')            // a backslash?
!                     state = BACKSLASH;
! 
!                 newsql.append(c);
!                 break;
! 
!             case BACKSLASH:
!                 state = IN_STRING;
! 
!                 newsql.append(c);
!                 break;
! 
!             case ESC_TIMEDATE:
!                 if(c == '}')
!                     state = IN_SQLCODE;       // end of escape code.
!                 else
!                     newsql.append(c);
!                 break;
!             } // end switch
!         }
! 
!         return newsql.toString();
      }
  }

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://www.postgresql.org/search.mpl

Reply via email to