Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified BabelfishCompass_UserGuide.docx
Binary file not shown.
Binary file modified BabelfishCompass_UserGuide.pdf
Binary file not shown.
12 changes: 9 additions & 3 deletions BabelfishFeatures.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
# this must always be the first section:
[Babelfish for T-SQL]
# only Babelfish version numbers listed here can be referenced the rules below:
valid_versions=1.0.0, 1.1.0, 1.2.0, 1.3.0, 1.4.0, 1.5.0, 1.6.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 3.1.0, 3.2.0, 3.3.0, 3.4.0, 3.5.0, 4.0.0, 4.1.0, 4.2.0, 4.3.0, 4.4.0, 4.5.0, 5.1.0
valid_versions=1.0.0, 1.1.0, 1.2.0, 1.3.0, 1.4.0, 1.5.0, 1.6.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 3.1.0, 3.2.0, 3.3.0, 3.4.0, 3.5.0, 4.0.0, 4.1.0, 4.2.0, 4.3.0, 4.4.0, 4.5.0, 4.6.0, 5.1.0, 5.2.0
# x.y.1/2/3 etc are bugfix releases for x.y.0 (no new T-SQL features supported), and are typically based on a newer PG release
file_format=2 # version number for format of this .cfg file. This is not expected to change much
file_timestamp=Apr-2025 # identifies the version of this file, together with the latest Babelfish version supported
file_timestamp=Jun-2025 # identifies the version of this file, together with the latest Babelfish version supported
# format: dd-MON-yyyy or MON-yyyy

# Basic principle:
Expand Down Expand Up @@ -222,6 +222,8 @@ rule=function_call
supported-3.5.0-3.*=STX,STY,LAT,LONG,STASTEXT,STASBINARY,STDISTANCE,STPOINTFROMTEXT,STGEOMFROMTEXT,POINT
supported-4.1.0=STX,STY,LAT,LONG,STASTEXT,STASBINARY,STDISTANCE,STPOINTFROMTEXT,STGEOMFROMTEXT,POINT
supported-4.3.0=STCONTAINS,STEQUALS,STAREA
supported-4.6.0-4.*=STDIMENSION,STDISJOINT,STINTERSECTS,STISCLOSED,STISEMPTY,STISVALID
supported-5.2.0=STDIMENSION,STDISJOINT,STINTERSECTS,STISCLOSED,STISEMPTY,STISVALID
report_group=Geospatial
complexity_score=HIGH

Expand Down Expand Up @@ -611,6 +613,8 @@ supported-1.0.0=arg4=NO_SUPPORTED_ARGUMENTS_RIGHT_NOW

[ALTER VIEW]
rule=create_or_alter_view
supported-4.6.0-4.*=*
supported-5.2.0=*
report_group=Views
complexity_score=HIGH

Expand Down Expand Up @@ -1182,6 +1186,8 @@ report_group=DML

[SELECT..UNPIVOT]
rule=unpivot_clause
supported-4.6.0-4.*=*
supported-5.2.0=*
report_group=DML

[SELECT TOP WITH TIES]
Expand Down Expand Up @@ -1681,5 +1687,5 @@ report_group=Identifiers
complexity_score=LOW

#-----------------------------------------------------------------------------------
#file checksum=07cb0775
#file checksum=660d1fd5
#--- end ---------------------------------------------------------------------------
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 2025-06
- Added support for Babelfish v.5.2.0 and v.4.6.0.
- Detect ALTER VIEW and UNPIVOT operations.
- Detect geospatial functions: STDimension, STDisjoint, STIntersects, STIsClosed, STIsEmpty, STIsValid

# 2025-04
- Added support for Babelfish v.5.1.0 and v.4.5.0.
- Detect various server-level and database-level fixed roles.
Expand Down
43 changes: 41 additions & 2 deletions src/main/java/compass/CompassAnalyze.java
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ else if (CompassUtilities.grammarRuleNames[ruleIxParent].equals(parentRuleName))
return findParent(parent.parent, parentRuleName);
}

// covnert a section of a parse tree to text
// convert a section of a parse tree to text
public String parseTreeToString(RuleContext ctx) {
String treeString = "";
TSQLParser parser = new TSQLParser(null);
Expand Down Expand Up @@ -767,6 +767,27 @@ private String lookupProc(String name) {
return resultType;
}

// is there a trigger on this view? this can only be an INSTEAD-OF trigger
private String lookupTrigOnView(String viewName) {
u.appOutput("viewName=["+viewName+"] ");
viewName = u.resolveName(viewName);
u.appOutput("viewName resolved=["+viewName+"] ");
String trigName = "";
for (String trig : CompassUtilities.trigSymTab.keySet()) {
String rawAttributes = CompassUtilities.trigSymTab.get(trig);
List<String> trigAttributes = new ArrayList<String>(Arrays.asList(rawAttributes.split(u.symTabSeparator2)));
String trigType = trigAttributes.get(0);
String baseTable = trigAttributes.get(1);
if (!trigType.equals("INSTEAD OF")) continue;
u.appOutput("trigAttributes=["+trigAttributes+"] baseTable=["+baseTable+"] viewName=["+viewName+"] ");
if (baseTable.equals(viewName)) {
trigName = trig;
break;
}
}
return trigName;
}

// lookup a column; must be called with resolved object name
private String lookupCol(String objName, String colName) {
String resultType = "";
Expand Down Expand Up @@ -1645,6 +1666,15 @@ private void HandleSystemProcPass1(TSQLParser.Func_proc_name_server_database_sch
@Override public String visitCreate_or_alter_dml_trigger(TSQLParser.Create_or_alter_dml_triggerContext ctx) {
if (u.debugging) dbgTraceVisitEntry(CompassUtilities.thisProc());
String trigName = ctx.simple_name().getText();
String trigType = "";
if ((ctx.FOR() != null) || (ctx.AFTER() != null)) {
trigType = "FOR/AFTER";
}
else if (ctx.INSTEAD() != null) {
trigType = "INSTEAD OF";
}
String trigBaseTable = ctx.table_name().getText();
u.addTrigSymTab(trigName, trigType, trigBaseTable);

// set context
u.setContext("TRIGGER", trigName);
Expand Down Expand Up @@ -5723,12 +5753,21 @@ else if (objType.equalsIgnoreCase("TRIGGER")) {

String kwd = "CREATE";
String status = u.Supported;
String hasTrigger = null;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use boolean instead of string

if (ctx.ALTER() != null) {
kwd = "ALTER";
if (ctx.CREATE() != null) kwd = "CREATE OR ALTER";
status = featureSupportedInVersion("ALTER VIEW"); // ALTER and CREATE OR ALTER go together

String trigName = lookupTrigOnView(viewName);
if (!trigName.isEmpty()) {
status = u.NotSupported;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have to add an item to the .cfg file and specifically test for that. you cannot just decide here that it is not supported

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added list item - View (representing Alter view) and Trigger (representing Alter view with trigger) in .cfg file

hasTrigger = "with trigger";
}
}
if (!hasTrigger) {
captureItem(kwd + " VIEW" + hasTrigger, viewName, ViewsReportGroup, kwd + " VIEW" + hasTrigger, status, ctx.start.getLine(), batchLines.toString());
}
captureItem(kwd + " VIEW", viewName, ViewsReportGroup, "", status, ctx.start.getLine(), batchLines.toString());

// set context
u.setContext("VIEW", viewName);
Expand Down
46 changes: 40 additions & 6 deletions src/main/java/compass/CompassUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public class CompassUtilities {
public static boolean onLinux = false;
public static String onPlatform = uninitialized;

public static final String thisProgVersion = "2025-04";
public static final String thisProgVersionDate = "April 2025";
public static final String thisProgVersion = "2025-06";
public static final String thisProgVersionDate = "June 2025";
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How sure are we that this is not going to be in May 2025 or July 2025?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Release is scheduled for June 1st week. Will update timestamp incase of delays.

public static final String thisProgName = "Babelfish Compass";
public static final String thisProgNameLong = "Compatibility assessment tool for Babelfish for PostgreSQL";
public static final String thisProgNameExec = "Compass";
Expand Down Expand Up @@ -112,8 +112,8 @@ public class CompassUtilities {
public String targetBabelfishVersionReportLine = "Target Babelfish version : v."; // line in report listing the target version
public boolean stdReport = false; // development only

public static List<String> BabelfishVersionList = Arrays.asList("1.0.0", "1.1.0", "1.2.0", "1.3.0", "1.4.0", "1.5.0", "2.1.0", "2.2.0", "2.3.0", "2.4.0", "3.1.0", "3.2.0", "3.3.0", "3.4.0", "3.5.0", "4.0.0", "4.1.0", "4.2.0", "4.3.0", "4.4.0", "4.5.0", "5.1.0");
public static List<String> BabelfishPGVersionList = Arrays.asList("13.4", "13.5", "13.6", "13.7", "13.8", "13.9", "14.3/4", "14.5", "14.6", "14.7", "15.2", "15.3", "15.4", "15.5", "15.6", "16.1", "16.2", "16.3", "16.4", "16.6", "16.8", "17.4");
public static List<String> BabelfishVersionList = Arrays.asList("1.0.0", "1.1.0", "1.2.0", "1.3.0", "1.4.0", "1.5.0", "2.1.0", "2.2.0", "2.3.0", "2.4.0", "3.1.0", "3.2.0", "3.3.0", "3.4.0", "3.5.0", "4.0.0", "4.1.0", "4.2.0", "4.3.0", "4.4.0", "4.5.0", "4.6.0", "5.1.0", "5.2.0");
public static List<String> BabelfishPGVersionList = Arrays.asList("13.4", "13.5", "13.6", "13.7", "13.8", "13.9", "14.3/4", "14.5", "14.6", "14.7", "15.2", "15.3", "15.4", "15.5", "15.6", "16.1", "16.2", "16.3", "16.4", "16.6", "16.8", "16.9", "17.4", "17.5");

// minimum Babelfish version; this is fixed
public static final String baseBabelfishVersion = "1.0.0";
Expand Down Expand Up @@ -713,6 +713,7 @@ public class CompassUtilities {
"ALTER SERVER ROLE"+tttSeparator+"ALTER SERVER ROLE for this server-level role is not currently supported",
"CREATE USER"+tttSeparator+"DB users are not currently supported, except 'dbo' and 'guest'",
"ALTER USER"+tttSeparator+"DB users are not currently supported, except 'dbo' and 'guest'",
"ALTER VIEW with trigger"+tttSeparator+"ALTER VIEW on View having trigger is not supported",
"ALTER VIEW"+tttSeparator+"ALTER VIEW is not currently supported; use DROP+CREATE",
"CREATE OR ALTER VIEW"+tttSeparator+"CREATE OR ALTER VIEW is not currently supported; use DROP+CREATE",
"ALTER PROCEDURE"+tttSeparator+"ALTER PROCEDURE is not currently supported; use DROP+CREATE",
Expand Down Expand Up @@ -1056,6 +1057,7 @@ public class CompassUtilities {
public String captureFilePathName;
public BufferedWriter captureFileWriter;
public static final String symTabSeparator = ";";
public static final String symTabSeparator2 = "~~";
public static final char metricsLineChar1 = '*';
public static final char metricsLineChar2 = '=';
public static final String metricsLineTag = "metrics";
Expand Down Expand Up @@ -1161,6 +1163,7 @@ public class CompassUtilities {
public static Map<String, String> SUDFSymTab = new HashMap<>();
public static Map<String, String> TUDFSymTab = new HashMap<>();
public static Map<String, String> procSymTab = new HashMap<>();
public static Map<String, String> trigSymTab = new HashMap<>();
public static Map<String, String> colSymTab = new HashMap<>(); // columns
public static boolean buildColSymTab = false; // false=no columns in symtab in pass 1
public static Map<String, String> parSymTab = new HashMap<>(); // parameters with defaults
Expand Down Expand Up @@ -4411,7 +4414,21 @@ public void addProcSymTab(String procName, String objType, boolean readingSymTab
procName = resolveName(procName);
}
procSymTab.put(procName.toUpperCase(), objType.toUpperCase());
}
}

// add to symbol table
public void addTrigSymTab(String trigName, String trigType, String baseTable) {
addTrigSymTab(trigName, trigType, baseTable, false);
}
public void addTrigSymTab(String trigName, String trigType, String baseTable, boolean readingSymTab)
{
if (!readingSymTab) {
trigName = resolveName(trigName);
baseTable = resolveName(baseTable);
}
String value = trigType.toUpperCase() + symTabSeparator2 + baseTable;
trigSymTab.put(trigName.toUpperCase(), value);
}

// add to symbol table
public String makeColSymTabKey(String tableName, String colName) {
Expand Down Expand Up @@ -4543,6 +4560,10 @@ public void writeSymTab(String reportName, String inputFileName, String appName)
for (String proc : procSymTab.keySet()) {
line = "proc" + symTabSeparator + maskChar(proc, symTabSeparator) + symTabSeparator + maskChar(procSymTab.get(proc), symTabSeparator);
writeSymTabFile(decodeIdentifier(line));
}
for (String trig : trigSymTab.keySet()) {
line = "trig" + symTabSeparator + maskChar(trig, symTabSeparator) + symTabSeparator + maskChar(trigSymTab.get(trig), symTabSeparator);
writeSymTabFile(decodeIdentifier(line));
}
for (String col : colSymTab.keySet()) {
line = "col" + symTabSeparator + col + symTabSeparator + maskChar(colSymTab.get(col), symTabSeparator);
Expand Down Expand Up @@ -4622,7 +4643,7 @@ public void readSymTab(String reportName, String appName) throws IOException
}
inFileReader.close();
}
int nrSymtab = (tableViewSymTab.size()+SUDFSymTab.size()+TUDFSymTab.size()+UDDSymTab.size()+colSymTab.size()+parSymTab.size()+procSymTab.size());
int nrSymtab = (tableViewSymTab.size()+SUDFSymTab.size()+TUDFSymTab.size()+UDDSymTab.size()+colSymTab.size()+parSymTab.size()+procSymTab.size()+trigSymTab.size());
if (debugging) dbgOutput("symtab entries=["+nrSymtab+"] ", debugSymtab);
if (debugSymtab) {
//dumpSymTab("after reading from disk");
Expand Down Expand Up @@ -4667,6 +4688,14 @@ else if (fields.get(0).equals("proc")) {
String objType = unmaskChar(fields.get(2),symTabSeparator);
addProcSymTab(objName, objType, true);
}
else if (fields.get(0).equals("trig")) {
String objName = unmaskChar(fields.get(1),symTabSeparator);
String rawAttributes = unmaskChar(fields.get(2),symTabSeparator);
List<String> trigAttributes = new ArrayList<String>(Arrays.asList(rawAttributes.split(symTabSeparator2)));
String trigType = trigAttributes.get(0);
String baseTable = trigAttributes.get(1);
addTrigSymTab(objName, trigType, baseTable, true);
}
else if (fields.get(0).equals("col")) {
String tableName = unmaskChar(fields.get(1),symTabSeparator);
String colName = unmaskChar(fields.get(2),symTabSeparator);
Expand Down Expand Up @@ -4699,6 +4728,7 @@ public static void clearSymTab()
TUDFSymTab.clear();
UDDSymTab.clear();
procSymTab.clear();
trigSymTab.clear();
colSymTab.clear();
parSymTab.clear();
SUDFNamesLikeXML.clear();
Expand Down Expand Up @@ -4743,6 +4773,10 @@ public void dumpSymTab(String tag)
countSymTab++;
}
appOutput("");
for (String trig: trigSymTab.keySet()) {
appOutput("trig=["+trig+"] => ["+trigSymTab.get(trig)+"]");
countSymTab++;
}
appOutput("SUDFNamesLikeXML: "+SUDFNamesLikeXML.size());
for (String sudf: SUDFNamesLikeXML.keySet()) {
appOutput("sudf=["+sudf+"] => ["+SUDFNamesLikeXML.get(sudf)+"]");
Expand Down
Loading