Skip to content

Commit 8556ad3

Browse files
authored
Merge pull request #822 from tomershay/support_full_text_search
Add support for full text search (MATCH..AGAINST)
2 parents c88f5ba + 6750a53 commit 8556ad3

File tree

7 files changed

+143
-0
lines changed

7 files changed

+143
-0
lines changed

src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public interface ExpressionVisitor {
7272

7373
void visit(InExpression inExpression);
7474

75+
void visit(FullTextSearch fullTextSearch);
76+
7577
void visit(IsNullExpression isNullExpression);
7678

7779
void visit(IsBooleanExpression isBooleanExpression);

src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@ public void visit(IsNullExpression expr) {
177177
expr.getLeftExpression().accept(this);
178178
}
179179

180+
@Override
181+
public void visit(FullTextSearch expr) {
182+
for (Column col : expr.getMatchColumns()) {
183+
col.accept(this);
184+
}
185+
}
186+
180187
@Override
181188
public void visit(IsBooleanExpression expr) {
182189
expr.getLeftExpression().accept(this);
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2019 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.expression.operators.relational;
11+
12+
import net.sf.jsqlparser.expression.Expression;
13+
import net.sf.jsqlparser.expression.ExpressionVisitor;
14+
import net.sf.jsqlparser.expression.StringValue;
15+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
16+
import net.sf.jsqlparser.schema.Column;
17+
18+
import java.util.Iterator;
19+
import java.util.List;
20+
21+
public class FullTextSearch extends ASTNodeAccessImpl implements Expression {
22+
23+
private List<Column> _matchColumns;
24+
private StringValue _againstValue;
25+
private String _searchModifier;
26+
27+
public FullTextSearch() {
28+
29+
}
30+
31+
public void setMatchColumns(List<Column> columns) {
32+
this._matchColumns = columns;
33+
}
34+
35+
public List<Column> getMatchColumns() {
36+
return this._matchColumns;
37+
}
38+
39+
public void setAgainstValue(StringValue val) {
40+
this._againstValue = val;
41+
}
42+
43+
public StringValue getAgainstValue() {
44+
return this._againstValue;
45+
}
46+
47+
public void setSearchModifier(String val) {
48+
this._searchModifier = val;
49+
}
50+
51+
public String getSearchModifier() {
52+
return this._searchModifier;
53+
}
54+
55+
@Override
56+
public void accept(ExpressionVisitor expressionVisitor) {
57+
expressionVisitor.visit(this);
58+
}
59+
60+
@Override
61+
public String toString() {
62+
// Build a list of matched columns
63+
String columnsListCommaSeperated = "";
64+
Iterator<Column> iterator = this._matchColumns.iterator();
65+
while (iterator.hasNext()) {
66+
Column col = iterator.next();
67+
columnsListCommaSeperated += col.getFullyQualifiedName();
68+
if (iterator.hasNext()) {
69+
columnsListCommaSeperated += ",";
70+
}
71+
}
72+
return "MATCH (" + columnsListCommaSeperated + ") AGAINST (" + this._againstValue + " " + this._searchModifier + ")";
73+
}
74+
}

src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,10 @@ public void visit(InExpression inExpression) {
276276
inExpression.getRightItemsList().accept(this);
277277
}
278278

279+
@Override
280+
public void visit(FullTextSearch fullTextSearch) {
281+
}
282+
279283
@Override
280284
public void visit(SignedExpression signedExpression) {
281285
signedExpression.getExpression().accept(this);

src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,21 @@ public void visit(InExpression inExpression) {
203203
inExpression.getRightItemsList().accept(this);
204204
}
205205

206+
@Override
207+
public void visit(FullTextSearch fullTextSearch) {
208+
// Build a list of matched columns
209+
String columnsListCommaSeperated = "";
210+
Iterator<Column> iterator = fullTextSearch.getMatchColumns().iterator();
211+
while (iterator.hasNext()) {
212+
Column col = iterator.next();
213+
columnsListCommaSeperated += col.getFullyQualifiedName();
214+
if (iterator.hasNext()) {
215+
columnsListCommaSeperated += ",";
216+
}
217+
}
218+
buffer.append("MATCH (" + columnsListCommaSeperated + ") AGAINST (" + fullTextSearch.getAgainstValue() + " " + fullTextSearch.getSearchModifier() + ")");
219+
}
220+
206221
@Override
207222
public void visit(SignedExpression signedExpression) {
208223
buffer.append(signedExpression.getSign());

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
107107
<K_ACTION: "ACTION">
108108
| <K_ADD:"ADD">
109109
| <K_ADVANCE:"ADVANCE">
110+
| <K_AGAINST:"AGAINST">
110111
| <K_ALGORITHM: "ALGORITHM">
111112
| <K_ALL:"ALL">
112113
| <K_ALTER:"ALTER">
@@ -205,6 +206,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
205206
| <K_LIKE:"LIKE">
206207
| <K_LIMIT:"LIMIT">
207208
| <K_LOW_PRIORITY : "LOW_PRIORITY">
209+
| <K_MATCH: "MATCH">
208210
| <K_MATCHED: "MATCHED">
209211
| <K_MATERIALIZED:"MATERIALIZED">
210212
| <K_MERGE: "MERGE">
@@ -2809,6 +2811,8 @@ Expression PrimaryExpression() #PrimaryExpression:
28092811

28102812
| LOOKAHEAD(FunctionWithCondParams()) retval = FunctionWithCondParams()
28112813

2814+
| LOOKAHEAD(FullTextSearch()) retval = FullTextSearch()
2815+
28122816
| LOOKAHEAD(Function()) retval=Function() [ LOOKAHEAD(2) retval = AnalyticExpression((Function)retval) ]
28132817

28142818
| LOOKAHEAD(2) retval = IntervalExpression() { dateExpressionAllowed = false; }
@@ -3224,6 +3228,31 @@ Execute Execute(): {
32243228
}
32253229
}
32263230

3231+
FullTextSearch FullTextSearch() : {
3232+
Column col;
3233+
Token searchModifier;
3234+
Token againstValue;
3235+
FullTextSearch fs = new FullTextSearch();
3236+
List<Column> matchedColumns = new ArrayList<Column>();
3237+
List<Expression> expList = new ArrayList<Expression>();
3238+
}
3239+
{
3240+
<K_MATCH> "(" col=Column() { matchedColumns.add(col); } ("," col=Column() { matchedColumns.add(col); } )* ")" <K_AGAINST>
3241+
"(" againstValue=<S_CHAR_LITERAL> { fs.setAgainstValue(new StringValue(againstValue.image)); }
3242+
(
3243+
searchModifier="IN NATURAL LANGUAGE MODE"
3244+
| searchModifier="IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION"
3245+
| searchModifier="IN BOOLEAN MODE"
3246+
| searchModifier="WITH QUERY EXPANSION"
3247+
)
3248+
{ fs.setSearchModifier(searchModifier.image); }
3249+
")"
3250+
{
3251+
fs.setMatchColumns(matchedColumns);
3252+
return fs;
3253+
}
3254+
}
3255+
32273256
Function FunctionWithCondParams() #Function: {
32283257
Function retval = new Function();
32293258
String funcName = null;

src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,6 +1852,18 @@ public void testFunctionRight() throws JSQLParserException {
18521852
assertSqlCanBeParsedAndDeparsed(statement);
18531853
}
18541854

1855+
@Test
1856+
public void testOneColumnFullTextSearchMySQL() throws JSQLParserException {
1857+
String statement = "SELECT MATCH (col1) AGAINST ('test' IN NATURAL LANGUAGE MODE) relevance FROM tbl";
1858+
assertSqlCanBeParsedAndDeparsed(statement);
1859+
}
1860+
1861+
@Test
1862+
public void testSeveralColumnsFullTextSearchMySQL() throws JSQLParserException {
1863+
String statement = "SELECT MATCH (col1,col2,col3) AGAINST ('test' IN NATURAL LANGUAGE MODE) relevance FROM tbl";
1864+
assertSqlCanBeParsedAndDeparsed(statement);
1865+
}
1866+
18551867
@Test
18561868
public void testIsTrue() throws JSQLParserException {
18571869
String statement = "SELECT col FROM tbl WHERE col IS TRUE";

0 commit comments

Comments
 (0)