Commit 6e63468f authored by Bruce Momjian's avatar Bruce Momjian

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.

Thomas O'Dowd
parent c6cb8701
......@@ -39,6 +39,11 @@ public abstract class Statement {
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,26 +231,76 @@ public abstract class Statement {
}
/**
* This is an attempt to implement SQL Escape clauses
* 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) {
// 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;
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();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment