From 9fa80a98122c16d04112aed592b71579fceaf599 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Sat, 13 Jan 2007 07:27:44 +0000 Subject: [PATCH] fix the error with modifying keywords within quotes fix the error of cutting double spaces within quotes bring back support for convertAlias for 8.1 support --- .../dbPort/ConvertMap_PostgreSQL.java | 27 ++-- .../compiere/dbPort/Convert_PostgreSQL.java | 127 +++++++++--------- .../dbPort/Convert_PostgreSQLTest.java | 28 ++-- 3 files changed, 92 insertions(+), 90 deletions(-) diff --git a/dbPort/src/org/compiere/dbPort/ConvertMap_PostgreSQL.java b/dbPort/src/org/compiere/dbPort/ConvertMap_PostgreSQL.java index 9f87d57b94..f22ddac38d 100644 --- a/dbPort/src/org/compiere/dbPort/ConvertMap_PostgreSQL.java +++ b/dbPort/src/org/compiere/dbPort/ConvertMap_PostgreSQL.java @@ -24,22 +24,21 @@ public final class ConvertMap_PostgreSQL { // Oracle Pattern Replacement // Data Types - s_pg.put("\\b NUMBER \\b", " NUMERIC "); - s_pg.put("\\b NUMBER(\\b", " NUMERIC("); + s_pg.put("\\bNUMBER\\b", "NUMERIC"); s_pg.put("\\bDATE\\b", "TIMESTAMP"); s_pg.put("\\bVARCHAR2\\b", "VARCHAR"); s_pg.put("\\bNVARCHAR2\\b", "VARCHAR"); s_pg.put("\\bNCHAR\\b", "CHAR"); - //begin vpj-cd e-evolution 03/11/2005 PostgreSQL + //begin vpj-cd e-evolution 03/11/2005 PostgreSQL s_pg.put("\\bBLOB\\b", "BYTEA"); // BLOB not directly supported s_pg.put("\\bCLOB\\b", "BYTEA"); // CLOB not directly supported - s_pg.put("\\bLIMIT\\b","\"limit\""); - s_pg.put("\\bACTION\\b","\"action\""); - s_pg.put("\\bold\\b","\"old\""); - s_pg.put("\\bnew\\b","\"new\""); + s_pg.put("\\bLIMIT\\b","\"limit\""); + s_pg.put("\\bACTION\\b","\"action\""); + s_pg.put("\\bold\\b","\"old\""); + s_pg.put("\\bnew\\b","\"new\""); //s_pg.put("\\bBLOB\\b", "OID"); // BLOB not directly supported //s_pg.put("\\bCLOB\\b", "OID"); // CLOB not directly supported - //end vpj-cd e-evolution 03/11/2005 PostgreSQL + //end vpj-cd e-evolution 03/11/2005 PostgreSQL // Storage s_pg.put("\\bCACHE\\b", ""); @@ -51,11 +50,6 @@ public final class ConvertMap_PostgreSQL { // Functions s_pg.put("\\bSYSDATE\\b", "CURRENT_TIMESTAMP"); // alternative: NOW() - //Bug fix, Gunther Hoppe 08.07.2005 e-evolution - //Begin ---------------------------------------------------------------------------------------- - s_pg.put("\\bSysDate\\b", "CURRENT_TIMESTAMP"); - s_pg.put("SysDate", "CURRENT_TIMESTAMP"); - //end ---------------------------------------------------------------------------------------- //begin vpj-cd e-evolution 03/11/2005 PostgreSQL s_pg.put("\\bDUMP\\b", "MD5"); s_pg.put("END CASE", "END"); @@ -71,11 +65,11 @@ public final class ConvertMap_PostgreSQL { s_pg.put("\\bON COMMIT DELETE ROWS\\b", ""); s_pg.put("\\bON COMMIT PRESERVE ROWS\\b", ""); - //DDL + //DDL - // begin vpj-cd e-evolution 08/02/2005 PostgreSQL + // begin vpj-cd e-evolution 08/02/2005 PostgreSQL //s_pg.put("\\bMODIFY\\b","ALTER COLUMN"); - //s_pg.put("\\bDEFAULT\\b","SET DEFAULT"); + //s_pg.put("\\bDEFAULT\\b","SET DEFAULT"); // end vpj-cd e-evolution 08/02/2005 PostgreSQL // DROP TABLE x CASCADE CONSTRAINTS @@ -88,7 +82,6 @@ public final class ConvertMap_PostgreSQL { s_pg.put("\\bELSIF\\b", "ELSE IF"); // begin vpj-cd e-evolution 03/11/2005 PostgreSQL s_pg.put("\\bREC \\b", "AS REC "); - //s_pg.put("\\bAND\\sROWNUM=\\b", "LIMIT "); // end vpj-cd e-evolution 03/11/2005 PostgreSQL // Sequences diff --git a/dbPort/src/org/compiere/dbPort/Convert_PostgreSQL.java b/dbPort/src/org/compiere/dbPort/Convert_PostgreSQL.java index 4afe3a0702..663513052a 100644 --- a/dbPort/src/org/compiere/dbPort/Convert_PostgreSQL.java +++ b/dbPort/src/org/compiere/dbPort/Convert_PostgreSQL.java @@ -27,7 +27,7 @@ import org.compiere.util.Util; /** * Convert Oracle SQL to PostgreSQL SQL * - * @author Victor Perez, Low Heng Sin + * @author Victor Perez, Low Heng Sin, Carlos Ruiz */ public class Convert_PostgreSQL extends Convert_SQL92 { /** @@ -38,14 +38,16 @@ public class Convert_PostgreSQL extends Convert_SQL92 { } // Convert /** RegEx: insensitive and dot to include line end characters */ - public static final int REGEX_FLAGS = Pattern.CASE_INSENSITIVE - | Pattern.DOTALL; + public static final int REGEX_FLAGS = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; private TreeMap m_map; /** Logger */ private static CLogger log = CLogger.getCLogger(Convert_PostgreSQL.class); + /** Vector to save previous values of quoted strings **/ + private Vector retVars = new Vector(); + /** * Is Oracle DB * @@ -66,7 +68,10 @@ public class Convert_PostgreSQL extends Convert_SQL92 { ArrayList result = new ArrayList(); // remove comments - String statement = removeComments(sqlStatement); + String statement = sqlStatement; + statement = replaceQuotedStrings(statement); + statement = convertMapStatement(removeComments(statement)); + statement = recoverQuotedStrings(statement); // log.info("------------------------------------------------------------"); // log.info(statement); // log.info("------------------->"); @@ -77,39 +82,29 @@ public class Convert_PostgreSQL extends Convert_SQL92 { // Process if (isCreate && cmpString.indexOf(" FUNCTION ") != -1) result.addAll(convertFunction(statement)); - else if (isCreate && cmpString.indexOf(" TRIGGER ") != -1) result.addAll(convertTrigger(statement)); - else if (isCreate && cmpString.indexOf(" PROCEDURE ") != -1) result.addAll(convertProcedure(statement)); - else if (isCreate && cmpString.indexOf(" VIEW ") != -1) result.addAll(convertView(statement)); // begin vpj-cd e-evolution 02/24/2005 PostgreSQL else if (cmpString.indexOf("ALTER TABLE") != -1) { - result.add(convertDDL(converSimpleStatement(statement))); + result.add(convertDDL(convertComplexStatement(statement))); } else if (cmpString.indexOf("ROWNUM") != -1) { - result - .add(convertRowNum(converSimpleStatement(statement))); + result.add(convertRowNum(convertAlias(convertComplexStatement(statement)))); } else if (cmpString.indexOf("DELETE ") != -1 && cmpString.indexOf("DELETE FROM") == -1) { - statement = convertDelete(statement); cmpString = statement; - // System.out.println("-------------cmpString:"+cmpString); - result.add(converSimpleStatement(cmpString)); + result.add(convertComplexStatement(convertAlias(cmpString))); } else if (cmpString.indexOf("DELETE FROM") != -1) { - - result.add(converSimpleStatement(statement)); + result.add(convertComplexStatement(convertAlias(statement))); } else if (cmpString.indexOf("UPDATE ") != -1) { - result - .add(converSimpleStatement(convertUpdate(statement))); + result.add(convertComplexStatement(convertUpdate(convertAlias(statement)))); } else { - result.add(converSimpleStatement(statement)); + result.add(convertComplexStatement(convertAlias(statement))); } - // else - // result.add(converSimpleStatement(statement)); // end vpj-cd e-evolution 02/24/2005 PostgreSQL // Simple Statement @@ -128,7 +123,7 @@ public class Convert_PostgreSQL extends Convert_SQL92 { * @param sqlStatement * @return converted Statement */ - private String converSimpleStatement(String sqlStatement) { + private String convertMapStatement(String sqlStatement) { // Error Checks if (sqlStatement.toUpperCase().indexOf("EXCEPTION WHEN") != -1) { String error = "Exception clause needs to be converted: " @@ -138,41 +133,26 @@ public class Convert_PostgreSQL extends Convert_SQL92 { return sqlStatement; } - // Standard Statement + // Carlos Ruiz - globalqss + // Standard Statement -- change the keys in ConvertMap + String retValue = sqlStatement; + + Pattern p; + Matcher m; + + // for each iteration in the conversion map Iterator iter = m_map.keySet().iterator(); while (iter.hasNext()) { - // begin e-evolution vpj-cd 26.09.2005 - // search reserved word ie DATE into 'DATE' and remplace for - // character temporal <--> - Vector retVars = new Vector(); - Pattern p = Pattern.compile("'[[\\w]*[-:,\\(\\)]*[ ]*]*'"); - Matcher m = p.matcher(retValue); - while (m.find()) { - retVars.addElement(new String(retValue.substring(m.start(), m - .end()))); - } - retVars.addElement(new String(m.replaceAll("<-->"))); - // end e-evolution vpj-cd 26.09.2005*/ + + // replace the key on convertmap (i.e.: number by numeric) String regex = (String) iter.next(); - String replacement = (String) m_map.get(regex); + String replacement = (String) m_map.get(regex); try { - // begin e-evolution vpj-cd 29.09.2005 - // Pattern p = Pattern.compile(regex, REGEX_FLAGS ); - // Matcher m = p.matcher(retValue); - // retValue = m.replaceAll(replacement); - // remplace reserved work p = Pattern.compile(regex, REGEX_FLAGS); - m = p.matcher((String) retVars.get(retVars.size() - 1)); + m = p.matcher(retValue); retValue = m.replaceAll(replacement); - p = Pattern.compile("<-->", REGEX_FLAGS); - m = p.matcher(retValue); - for (int cont = 0; cont < retVars.size() - 1; cont++) { - retValue = m.replaceFirst((String) retVars.get(cont)); - m = p.matcher(retValue); - } - // end e-evolution vpj-cd 29.09.2005 } catch (Exception e) { String error = "Error expression: " + regex + " - " + e; log.info(error); @@ -180,10 +160,33 @@ public class Convert_PostgreSQL extends Convert_SQL92 { } } - // Convert Decode, Sequence, Join, .. - return convertComplexStatement(retValue); + return retValue; } // convertSimpleStatement + private String replaceQuotedStrings(String retValue) { + // save every value + // Pattern p = Pattern.compile("'[[\\w]*[-:,\\(\\)]*[ ]*]*'"); + // Carlos Ruiz - globalqss - better matching regexp + retVars.clear(); + Pattern p = Pattern.compile("'[[^']*]*'"); + Matcher m = p.matcher(retValue); + while (m.find()) { + retVars.addElement(new String(retValue.substring(m.start(), m.end()))); + } + retValue = m.replaceAll("<-->"); + return retValue; + } + + private String recoverQuotedStrings(String retValue) { + Pattern p = Pattern.compile("<-->", REGEX_FLAGS); + Matcher m = p.matcher(retValue); + for (int cont = 0; cont < retVars.size(); cont++) { + retValue = m.replaceFirst((String) retVars.get(cont)); + m = p.matcher(retValue); + } + return retValue; + } + /** * Clean up Statement. Remove all comments and while spaces Database * specific functionality can me tagged as follows: @@ -259,7 +262,7 @@ public class Convert_PostgreSQL extends Convert_SQL92 { private ArrayList convertFunction(String sqlStatement) { ArrayList result = new ArrayList(); // Convert statement - to avoid handling contents of comments - String stmt = converSimpleStatement(sqlStatement); + String stmt = sqlStatement; // Double quotes ' stmt = Pattern.compile("'").matcher(stmt).replaceAll("''"); // remove OR REPLACE @@ -391,7 +394,7 @@ public class Convert_PostgreSQL extends Convert_SQL92 { private ArrayList convertProcedure(String sqlStatement) { ArrayList result = new ArrayList(); // Convert statement - to avoid handling contents of comments - String stmt = converSimpleStatement(sqlStatement); + String stmt = sqlStatement; // Double quotes ' stmt = Pattern.compile("'").matcher(stmt).replaceAll("''"); // remove OR REPLACE @@ -516,7 +519,7 @@ public class Convert_PostgreSQL extends Convert_SQL92 { private ArrayList convertTrigger(String sqlStatement) { ArrayList result = new ArrayList(); // Convert statement - to avoid handling contents of comments - String stmt = converSimpleStatement(sqlStatement); + String stmt = sqlStatement; // Trigger specific replacements stmt = Pattern.compile("\\bINSERTING\\b").matcher(stmt).replaceAll( @@ -622,7 +625,7 @@ public class Convert_PostgreSQL extends Convert_SQL92 { */ private ArrayList convertView(String sqlStatement) { ArrayList result = new ArrayList(); - String stmt = converSimpleStatement(sqlStatement); + String stmt = sqlStatement; // remove OR REPLACE int orReplacePos = stmt.toUpperCase().indexOf(" OR REPLACE "); @@ -745,11 +748,9 @@ public class Convert_PostgreSQL extends Convert_SQL92 { * @return converted statement */ private String convertRowNum(String sqlStatement) { - log.info("RowNum<== " + sqlStatement); + // log.info("RowNum<== " + sqlStatement); - log.info("RowNum<== " + sqlStatement); - - sqlStatement = Pattern.compile("rownum",REGEX_FLAGS).matcher(sqlStatement).replaceAll("ROWNUM"); + sqlStatement = Pattern.compile("rownum",REGEX_FLAGS).matcher(sqlStatement).replaceAll("ROWNUM"); String retValue = null; @@ -1499,8 +1500,6 @@ public class Convert_PostgreSQL extends Convert_SQL92 { * @param sqlStatement * @return converted statementf */ - /** we Victor, Carlos , Heng sin, Kontro are agree to only support PostgreSQL 8.2 - * this methos now i comment until finish test with PostgreSQL 8.2 private String convertAlias(String sqlStatement) { String[] tokens = sqlStatement.split("\\s"); String table = null; @@ -1550,8 +1549,6 @@ public class Convert_PostgreSQL extends Convert_SQL92 { return sqlStatement; } } // - */ - // end vpj-cd e-evolution 02/24/2005 PostgreSQL // begin vpj-cd 08/02/2005 @@ -1584,7 +1581,6 @@ public class Convert_PostgreSQL extends Convert_SQL92 { int end_col = 0; int begin_default = -1; - int begin_type = -1; String column = null; String type = null; @@ -1647,7 +1643,8 @@ public class Convert_PostgreSQL extends Convert_SQL92 { return sqlStatement; } - private String convertIgnore(String sqlStatement) { +/* + private String convertIgnore(String sqlStatement) { String vars[] = new String[20]; int cont = 1; Pattern p = Pattern.compile("'[[\\w]*[,]*[ ]*]*'", @@ -1670,4 +1667,6 @@ public class Convert_PostgreSQL extends Convert_SQL92 { } return null; } +*/ + } // Convert diff --git a/dbPort/src/org/compiere/dbPort/Convert_PostgreSQLTest.java b/dbPort/src/org/compiere/dbPort/Convert_PostgreSQLTest.java index 4cba57db6c..e101d9f766 100644 --- a/dbPort/src/org/compiere/dbPort/Convert_PostgreSQLTest.java +++ b/dbPort/src/org/compiere/dbPort/Convert_PostgreSQLTest.java @@ -24,16 +24,30 @@ public final class Convert_PostgreSQLTest { public void doTest() { Convert_PostgreSQL convert = new Convert_PostgreSQL(); + String sql; + String sqe; + String[] r; + // test conversion of reserved words inside quotes + + sql = "UPDATE AD_Message_Trl SET MsgText='{0} Linea(s) {1,number,#,##0.00} - Total: {2,number,#,##0.00}',MsgTip=NULL,Updated=TO_DATE('2007-01-12 21:44:31','YYYY-MM-DD HH24:MI:SS'),IsTranslated='Y' WHERE AD_Message_ID=828 AND AD_Language='es_MX'"; + sqe = "UPDATE AD_Message_Trl SET MsgText='{0} Linea(s) {1,number,#,##0.00} - Total: {2,number,#,##0.00}',MsgTip=NULL,Updated=TO_TIMESTAMP('2007-01-12 21:44:31','YYYY-MM-DD HH24:MI:SS'),IsTranslated='Y' WHERE AD_Message_ID=828 AND AD_Language='es_MX'"; + + r = convert.convert(sql); + verify(sql, r, sqe); + + // uncomment to return without making the rest of tests + // if (true) return; + //financial report, bug [ 1580231 ] - String sql = "UPDATE t_report" + sql = "UPDATE t_report" + " SET (NAME, description) = (SELECT VALUE, NAME " + " FROM c_elementvalue" + " WHERE c_elementvalue_id = t_report.record_id) " + " WHERE record_id <> 0 " + " AND ad_pinstance_id = 1000024 " + " AND pa_reportline_id = 101 " + " AND fact_acct_id = 0 "; - String[] r = convert.convert(sql); + r = convert.convert(sql); verify(sql, r, "UPDATE t_report SET NAME=c_elementvalue.VALUE,description=c_elementvalue.NAME FROM c_elementvalue WHERE c_elementvalue.c_elementvalue_id = t_report.record_id AND t_report.record_id <> 0 AND t_report.ad_pinstance_id = 1000024 AND t_report.pa_reportline_id = 101 AND t_report.fact_acct_id = 0"); //from victor's test @@ -66,7 +80,7 @@ public final class Convert_PostgreSQLTest { + " Account_ID, PostingType, M_Product_ID, C_BPartner_ID," + " C_Project_ID, AD_OrgTrx_ID, C_SalesRegion_ID, C_Activity_ID," + " C_Campaign_ID, C_LocTo_ID, C_LocFrom_ID, User1_ID, User2_ID, GL_Budget_ID"; - String expected = "INSERT INTO Fact_Acct_Balance " + sqe = "INSERT INTO Fact_Acct_Balance " + "(AD_Client_ID, AD_Org_ID, C_AcctSchema_ID, DateAcct," + " Account_ID, PostingType, M_Product_ID, C_BPartner_ID," + " C_Project_ID, AD_OrgTrx_ID, C_SalesRegion_ID,C_Activity_ID," @@ -84,7 +98,7 @@ public final class Convert_PostgreSQLTest { + " C_Project_ID, AD_OrgTrx_ID, C_SalesRegion_ID, C_Activity_ID," + " C_Campaign_ID, C_LocTo_ID, C_LocFrom_ID, User1_ID, User2_ID, GL_Budget_ID"; r = convert.convert(sql); - verify(sql, r, expected); + verify(sql, r, sqe); //Doc_Invoice sql = "UPDATE M_Product_PO po " @@ -167,10 +181,6 @@ public final class Convert_PostgreSQLTest { r = convert.convert(sql); verify(sql, r, "UPDATE T_InventoryValue SET PricePO = (SELECT currencyConvert (po.PriceList,po.C_Currency_ID,T_InventoryValue.C_Currency_ID,T_InventoryValue.DateValue,null, po.AD_Client_ID,po.AD_Org_ID) FROM M_Product_PO po WHERE po.M_Product_ID=T_InventoryValue.M_Product_ID AND po.IsCurrentVendor='Y' LIMIT 1 ), PriceList = (SELECT currencyConvert(pp.PriceList,pl.C_Currency_ID,T_InventoryValue.C_Currency_ID,T_InventoryValue.DateValue,null, pl.AD_Client_ID,pl.AD_Org_ID) FROM M_PriceList pl, M_PriceList_Version plv, M_ProductPrice pp WHERE pp.M_Product_ID=T_InventoryValue.M_Product_ID AND pp.M_PriceList_Version_ID=T_InventoryValue.M_PriceList_Version_ID AND pp.M_PriceList_Version_ID=plv.M_PriceList_Version_ID AND plv.M_PriceList_ID=pl.M_PriceList_ID), PriceStd = (SELECT currencyConvert(pp.PriceStd,pl.C_Currency_ID,T_InventoryValue.C_Currency_ID,T_InventoryValue.DateValue,null, pl.AD_Client_ID,pl.AD_Org_ID) FROM M_PriceList pl, M_PriceList_Version plv, M_ProductPrice pp WHERE pp.M_Product_ID=T_InventoryValue.M_Product_ID AND pp.M_PriceList_Version_ID=T_InventoryValue.M_PriceList_Version_ID AND pp.M_PriceList_Version_ID=plv.M_PriceList_Version_ID AND plv.M_PriceList_ID=pl.M_PriceList_ID), PriceLimit = (SELECT currencyConvert(pp.PriceLimit,pl.C_Currency_ID,T_InventoryValue.C_Currency_ID,T_InventoryValue.DateValue,null, pl.AD_Client_ID,pl.AD_Org_ID) FROM M_PriceList pl, M_PriceList_Version plv, M_ProductPrice pp WHERE pp.M_Product_ID=T_InventoryValue.M_Product_ID AND pp.M_PriceList_Version_ID=T_InventoryValue.M_PriceList_Version_ID AND pp.M_PriceList_Version_ID=plv.M_PriceList_Version_ID AND plv.M_PriceList_ID=pl.M_PriceList_ID)"); - sql = "INSERT INTO AD_Message (msgtext) VALUES ('{0} Linea(s) {1,number,#,##0.00} - Total: {2,number,#,##0.00}')"; - r = convert.convert(sql); - verify(sql, r, "INSERT INTO AD_Message (msgtext) VALUES ('{0} Linea(s) {1,number,#,##0.00} - Total: {2,number,#,##0.00}')"); - } private void verify(String original, String[] converted, String expected) { @@ -195,4 +205,4 @@ public final class Convert_PostgreSQLTest { new Convert_PostgreSQLTest().doTest(); } -} +} \ No newline at end of file