Skip to content

Commit

Permalink
#42, #43. where LIKE
Browse files Browse the repository at this point in the history
Although these two issues appear to be similar, they are actually two different bugs.
#42 was matching the wildcard string anywhere in the field.  If 'Your%' was specified, it was supposed to be that 'Your' had to be at the line start.

#43.  from SUB-QUERY was converting everything in the sub-query to upper case.  So if you had any type of string comparison and it was specifying a string that had lower case, and the data was lower case - it was not matching since the lookup string had been converted to upper case.
  • Loading branch information
demmings committed May 2, 2023
1 parent e9b7761 commit df5c29b
Show file tree
Hide file tree
Showing 8 changed files with 2,653 additions and 2,509 deletions.
5,060 changes: 2,569 additions & 2,491 deletions coverage/tests.lcov

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions dist/gssql.js
Original file line number Diff line number Diff line change
Expand Up @@ -2525,7 +2525,7 @@ class SelectTables {
}

// @ts-ignore
const expanded = rightValue.replace(/%/g, ".*").replace(/_/g, ".");
const expanded = "^" + rightValue.replace(/%/g, ".*").replace(/_/g, ".");

const result = leftValue.search(expanded);
return result !== -1;
Expand Down Expand Up @@ -3930,8 +3930,9 @@ class TableFields {

// When subquery table data becomes data for the derived table name, references to
// original table names in column output needs to be changed to new derived table name.
if (columnTableNameReplacement !== null && columnOutput.startsWith(`${fld.originalTable}.`)) {
columnOutput = columnOutput.replace(`${fld.originalTable}.`, `${columnTableNameReplacement}.`);
if (columnTableNameReplacement !== null) {
const matchingTableIndex = columnOutput.toUpperCase().indexOf(`${fld.originalTable}.`);
columnOutput = matchingTableIndex === 0 ? columnTableNameReplacement + columnOutput.slice(matchingTableIndex + fld.originalTable.length) : columnOutput;
}
columnTitles.push(columnOutput);
}
Expand Down Expand Up @@ -6068,8 +6069,8 @@ class SelectKeywordAnalysis {
static parseForCorrelatedSubQuery(selectField) {
let subQueryAst = null;

const regExp = /\(\s*(SELECT[\s\S]+)\)/;
const matches = regExp.exec(selectField.toUpperCase());
const regExp = /\(\s*(SELECT[\s\S]+)\)/i;
const matches = regExp.exec(selectField);

if (matches !== null && matches.length > 1) {
subQueryAst = SqlParse.sql2ast(matches[1]);
Expand Down Expand Up @@ -6437,7 +6438,7 @@ class TableData { // skipcq: JS-0128
// Only change our CACHE STATUS if we have a lock.
const lock = LockService.getScriptLock();
try {
lock.waitLock(10000); // wait 10 seconds for others' use of the code section and lock to stop and then proceed
lock.waitLock(100000); // wait 100 seconds for others' use of the code section and lock to stop and then proceed
} catch (e) {
throw new Error("Cache lock failed");
}
Expand Down Expand Up @@ -6536,7 +6537,7 @@ class TableData { // skipcq: JS-0128
// Update status that cache is updated.
const lock = LockService.getScriptLock();
try {
lock.waitLock(10000); // wait 10 seconds for others' use of the code section and lock to stop and then proceed
lock.waitLock(100000); // wait 100 seconds for others' use of the code section and lock to stop and then proceed
} catch (e) {
throw new Error("Cache lock failed");
}
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@demmings/gssql",
"version": "1.3.4",
"version": "1.3.5",
"description": "Google Sheets QUERY function replacement using real SQL select syntax.",
"main": "testGsSql.js",
"files": ["./src", "src", "img", "dist"],
Expand Down
4 changes: 2 additions & 2 deletions src/SimpleParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1175,8 +1175,8 @@ class SelectKeywordAnalysis {
static parseForCorrelatedSubQuery(selectField) {
let subQueryAst = null;

const regExp = /\(\s*(SELECT[\s\S]+)\)/;
const matches = regExp.exec(selectField.toUpperCase());
const regExp = /\(\s*(SELECT[\s\S]+)\)/i;
const matches = regExp.exec(selectField);

if (matches !== null && matches.length > 1) {
subQueryAst = SqlParse.sql2ast(matches[1]);
Expand Down
66 changes: 65 additions & 1 deletion src/SqlTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -3717,6 +3717,66 @@ class SqlTester {
return this.isEqual("joinBigTables1", data.length, expected);
}

selectWhereLike3() {
let stmt = "select id, title, author_id from books where title like 'Your%'";

let data = new TestSql()
.addTableData("books", this.bookTable())
.enableColumnTitle(true)
.execute(stmt);

let expected = [["id", "title", "author_id"],
["2", "Your Trip", "15"],
["6", "Your Happy Life", "15"]];

return this.isEqual("selectWhereLike3", data, expected);
}

selectWhereLike4() {
let stmt = "select id, title, author_id from books where title like '%Your%'";

let data = new TestSql()
.addTableData("books", this.bookTable())
.enableColumnTitle(true)
.execute(stmt);

let expected = [["id", "title", "author_id"],
["2", "Your Trip", "15"],
["4", "Dream Your Life", "11"],
["6", "Your Happy Life", "15"]];

return this.isEqual("selectWhereLike4", data, expected);
}

selectFromSubQuery8() {
let stmt = "Select * from (select * from books where title like 'Your%') as mybooks";

let data = new TestSql()
.addTableData("books", this.bookTable())
.enableColumnTitle(true)
.execute(stmt);

let expected = [["MYBOOKS.ID", "MYBOOKS.TITLE", "MYBOOKS.TYPE", "MYBOOKS.AUTHOR_ID", "MYBOOKS.EDITOR_ID", "MYBOOKS.TRANSLATOR_ID"],
["2", "Your Trip", "translated", "15", "22", "32"],
["6", "Your Happy Life", "translated", "15", "22", "33"]];

return this.isEqual("selectFromSubQuery8", data, expected);
}

selectFromSubQuery9() {
let stmt = "Select * from (select * from books where title = 'Your Happy Life') as mybooks";

let data = new TestSql()
.addTableData("books", this.bookTable())
.enableColumnTitle(true)
.execute(stmt);

let expected = [["MYBOOKS.ID", "MYBOOKS.TITLE", "MYBOOKS.TYPE", "MYBOOKS.AUTHOR_ID", "MYBOOKS.EDITOR_ID", "MYBOOKS.TRANSLATOR_ID"],
["6", "Your Happy Life", "translated", "15", "22", "33"]];

return this.isEqual("selectFromSubQuery9", data, expected);
}

// S T A R T O T H E R T E S T S
removeTrailingEmptyRecords() {
let authors = this.authorsTable();
Expand Down Expand Up @@ -4359,7 +4419,7 @@ class SqlTester {

badJoin5() {
let stmt = "select invoice, name, title from customers inner join booksales on 'BB' + substr(booksales.customer_id, 2, 1) = 'BB' + substr(customers.id, 2, 1) join books on 'CC' + books.badColumnName = 'CC' + booksales.book_id";

let testSQL = new TestSql()
.addTableData("books", this.bookTable())
.addTableData("booksales", this.bookSalesTable())
Expand Down Expand Up @@ -4776,6 +4836,10 @@ function testerSql() {
// This test causes problems on gsSqlTest sheet (too big)
// result = result && tester.joinBigTables1();
result = result && tester.removeTrailingEmptyRecords();
result = result && tester.selectWhereLike3();
result = result && tester.selectWhereLike4();
result = result && tester.selectFromSubQuery8();
result = result && tester.selectFromSubQuery9();

Logger.log("============================================================================");

Expand Down
4 changes: 2 additions & 2 deletions src/TableData.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ class TableData { // skipcq: JS-0128
// Only change our CACHE STATUS if we have a lock.
const lock = LockService.getScriptLock();
try {
lock.waitLock(10000); // wait 10 seconds for others' use of the code section and lock to stop and then proceed
lock.waitLock(100000); // wait 100 seconds for others' use of the code section and lock to stop and then proceed
} catch (e) {
throw new Error("Cache lock failed");
}
Expand Down Expand Up @@ -357,7 +357,7 @@ class TableData { // skipcq: JS-0128
// Update status that cache is updated.
const lock = LockService.getScriptLock();
try {
lock.waitLock(10000); // wait 10 seconds for others' use of the code section and lock to stop and then proceed
lock.waitLock(100000); // wait 100 seconds for others' use of the code section and lock to stop and then proceed
} catch (e) {
throw new Error("Cache lock failed");
}
Expand Down
7 changes: 4 additions & 3 deletions src/Views.js
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ class SelectTables {
}

// @ts-ignore
const expanded = rightValue.replace(/%/g, ".*").replace(/_/g, ".");
const expanded = "^" + rightValue.replace(/%/g, ".*").replace(/_/g, ".");

const result = leftValue.search(expanded);
return result !== -1;
Expand Down Expand Up @@ -2258,8 +2258,9 @@ class TableFields {

// When subquery table data becomes data for the derived table name, references to
// original table names in column output needs to be changed to new derived table name.
if (columnTableNameReplacement !== null && columnOutput.startsWith(`${fld.originalTable}.`)) {
columnOutput = columnOutput.replace(`${fld.originalTable}.`, `${columnTableNameReplacement}.`);
if (columnTableNameReplacement !== null) {
const matchingTableIndex = columnOutput.toUpperCase().indexOf(`${fld.originalTable}.`);
columnOutput = matchingTableIndex === 0 ? columnTableNameReplacement + columnOutput.slice(matchingTableIndex + fld.originalTable.length) : columnOutput;
}
columnTitles.push(columnOutput);
}
Expand Down

0 comments on commit df5c29b

Please sign in to comment.