Skip to content

Commit

Permalink
Merge pull request #373 from v-xiangs/newdev-SET-FMTONLY-ON-to-suppor…
Browse files Browse the repository at this point in the history
…t-complex-query

Set fmtonly on to support complex query
  • Loading branch information
xiangyushawn authored Jul 21, 2017
2 parents 0d7d78b + a04d9ad commit 999cd00
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.sql.SQLException;
import java.sql.Statement;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
Expand Down Expand Up @@ -51,6 +52,9 @@ public final class SQLServerParameterMetaData implements ParameterMetaData {
static private final AtomicInteger baseID = new AtomicInteger(0); // Unique id generator for each instance (used for logging).
final private String traceID = " SQLServerParameterMetaData:" + nextInstanceID();
boolean isTVP = false;

private String stringToParse = null;
private int indexToBeginParse = -1;

// Returns unique id for each instance.
private static int nextInstanceID() {
Expand Down Expand Up @@ -85,9 +89,12 @@ final public String toString() {
String sLastField = null;
StringBuilder sb = new StringBuilder();

int sTokenIndex = 0;
while (st.hasMoreTokens()) {

String sToken = st.nextToken();
sTokenIndex = sTokenIndex + sToken.length();

if (sToken.equalsIgnoreCase(columnStartToken)) {
nState = PARAMNAME;
continue;
Expand Down Expand Up @@ -120,6 +127,7 @@ final public String toString() {
}
}

indexToBeginParse = sTokenIndex;
return sb.toString();
}

Expand All @@ -138,8 +146,11 @@ final public String toString() {
String sLastField = null;
StringBuilder sb = new StringBuilder();

int sTokenIndex = 0;
while (st.hasMoreTokens()) {
String sToken = st.nextToken();
sTokenIndex = sTokenIndex + sToken.length();

if (sToken.equalsIgnoreCase(columnMarker)) {
nState = 1;
continue;
Expand Down Expand Up @@ -169,6 +180,7 @@ final public String toString() {
}
}

indexToBeginParse = sTokenIndex;
return sb.toString();
}

Expand Down Expand Up @@ -391,12 +403,24 @@ private MetaInfo parseStatement(String sql,
}

if (null != metaTable) {
if (sTableMarker.equalsIgnoreCase("UPDATE"))
if (sTableMarker.equalsIgnoreCase("UPDATE")) {
metaFields = parseColumns(sql, "SET"); // Get the set fields
else if (sTableMarker.equalsIgnoreCase("INTO")) // insert
stringToParse = "";
}
else if (sTableMarker.equalsIgnoreCase("INTO")) { // insert
metaFields = parseInsertColumns(sql, "("); // Get the value fields
else
stringToParse = sql.substring(indexToBeginParse); // the index of ')'

// skip VALUES() clause
if (stringToParse.trim().toLowerCase().startsWith("values")) {
parseInsertColumns(stringToParse, "(");
stringToParse = stringToParse.substring(indexToBeginParse); // the index of ')'
}
}
else {
metaFields = parseColumns(sql, "WHERE"); // Get the where fields
stringToParse = "";
}

return new MetaInfo(metaTable, metaFields);
}
Expand Down Expand Up @@ -577,20 +601,54 @@ private void checkClosed() throws SQLServerException {
}
else {
// old implementation for SQL server 2008
MetaInfo metaInfo = parseStatement(sProcString);
if (null == metaInfo) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_cantIdentifyTableMetadata"));
Object[] msgArgs = {sProcString};
SQLServerException.makeFromDriverError(con, stmtParent, form.format(msgArgs), null, false);
}
stringToParse = sProcString;
ArrayList<MetaInfo> metaInfoList = new ArrayList<MetaInfo>();

while (stringToParse.length() > 0) {
MetaInfo metaInfo = parseStatement(stringToParse);
if (null == metaInfo) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_cantIdentifyTableMetadata"));
Object[] msgArgs = {stringToParse};
SQLServerException.makeFromDriverError(con, stmtParent, form.format(msgArgs), null, false);
}

if (metaInfo.fields.length() <= 0)
metaInfoList.add(metaInfo);
}
if (metaInfoList.size() <= 0 || metaInfoList.get(0).fields.length() <= 0) {
return;
}

StringBuilder sbColumns = new StringBuilder();

for (MetaInfo mi : metaInfoList) {
sbColumns = sbColumns.append(mi.fields + ",");
}
sbColumns.deleteCharAt(sbColumns.length() - 1);

String columns = sbColumns.toString();

StringBuilder sbTablesAndJoins = new StringBuilder();
for (int i = 0; i < metaInfoList.size(); i++) {
if (i == 0) {
sbTablesAndJoins = sbTablesAndJoins.append(metaInfoList.get(i).table);
}
else {
if (metaInfoList.get(i).table.equals(metaInfoList.get(i - 1).table)
&& metaInfoList.get(i).fields.equals(metaInfoList.get(i - 1).fields)) {
continue;
}
sbTablesAndJoins = sbTablesAndJoins
.append(" LEFT JOIN " + metaInfoList.get(i).table + " ON " + metaInfoList.get(i - 1).table + "."
+ metaInfoList.get(i - 1).fields + "=" + metaInfoList.get(i).table + "." + metaInfoList.get(i).fields);
}
}

String tablesAndJoins = sbTablesAndJoins.toString();

Statement stmt = con.createStatement();
String sCom = "sp_executesql N'SET FMTONLY ON SELECT " + metaInfo.fields + " FROM " + metaInfo.table + " WHERE 1 = 2'";
ResultSet rs = stmt.executeQuery(sCom);
String sCom = "sp_executesql N'SET FMTONLY ON SELECT " + columns + " FROM " + tablesAndJoins + " '";

ResultSet rs = stmt.executeQuery(sCom);
parseQueryMetaFor2008(rs);
stmt.close();
rs.close();
Expand Down
Loading

0 comments on commit 999cd00

Please sign in to comment.