Skip to content

Commit 7dd856c

Browse files
cr
1 parent 171f26c commit 7dd856c

File tree

6 files changed

+81
-47
lines changed

6 files changed

+81
-47
lines changed

src/dialect/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,11 @@ pub trait Dialect: Debug + Any {
840840
fn supports_timestamp_versioning(&self) -> bool {
841841
false
842842
}
843+
844+
/// Returns true if the dialect supports the table hints in the `FROM` clause.
845+
fn supports_table_hints(&self) -> bool {
846+
false
847+
}
843848
}
844849

845850
/// This represents the operators for which precedence must be defined

src/dialect/mysql.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ impl Dialect for MySqlDialect {
121121
|| (!keywords::RESERVED_FOR_TABLE_ALIAS.contains(kw)
122122
&& !RESERVED_FOR_TABLE_ALIAS_MYSQL.contains(kw))
123123
}
124+
125+
fn supports_table_hints(&self) -> bool {
126+
true
127+
}
124128
}
125129

126130
/// `LOCK TABLES`

src/parser/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11283,10 +11283,13 @@ impl<'a> Parser<'a> {
1128311283

1128411284
let alias = self.maybe_parse_table_alias()?;
1128511285

11286-
// maybe parse so we will still support queries like 'SELECT * FROM T USE LIMIT 1' in BigQuery, for example
11287-
let index_hints = self
11288-
.maybe_parse(|p| p.parse_table_index_hints())?
11289-
.unwrap_or(vec![]);
11286+
// MYSQL-specific table hints:
11287+
let index_hints = if self.dialect.supports_table_hints() {
11288+
self.maybe_parse(|p| p.parse_table_index_hints())?
11289+
.unwrap_or(vec![])
11290+
} else {
11291+
vec![]
11292+
};
1129011293

1129111294
// MSSQL-specific table hints:
1129211295
let mut with_hints = vec![];

tests/sqlparser_bigquery.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,34 +1602,6 @@ fn parse_join_constraint_unnest_alias() {
16021602
);
16031603
}
16041604

1605-
#[test]
1606-
fn parse_select_with_use() {
1607-
let sql = "SELECT * FROM T USE LIMIT 1";
1608-
let select =
1609-
bigquery().verified_only_select_with_canonical(sql, "SELECT * FROM T AS USE LIMIT 1");
1610-
assert_eq!(
1611-
select.from,
1612-
vec![TableWithJoins {
1613-
relation: TableFactor::Table {
1614-
name: ObjectName(vec![Ident::new("T")]),
1615-
alias: Some(TableAlias {
1616-
name: Ident::new("USE"),
1617-
columns: vec![],
1618-
}),
1619-
args: None,
1620-
with_hints: vec![],
1621-
version: None,
1622-
partitions: vec![],
1623-
with_ordinality: false,
1624-
json_path: None,
1625-
sample: None,
1626-
index_hints: vec![],
1627-
},
1628-
joins: vec![],
1629-
}]
1630-
);
1631-
}
1632-
16331605
#[test]
16341606
fn parse_merge() {
16351607
let sql = concat!(

tests/sqlparser_common.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10025,6 +10025,71 @@ fn parse_unpivot_table() {
1002510025
);
1002610026
}
1002710027

10028+
#[test]
10029+
fn parse_select_table_with_index_hints() {
10030+
let supported_dialects = all_dialects_where(|d| d.supports_table_hints());
10031+
let s = supported_dialects.verified_only_select(
10032+
"SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX FOR ORDER BY (i2) ORDER BY a",
10033+
);
10034+
if let TableFactor::Table { index_hints, .. } = &s.from[0].relation {
10035+
assert_eq!(
10036+
vec![
10037+
TableIndexHints {
10038+
hint_type: TableIndexHintType::Use,
10039+
index_names: vec!["i1".into()],
10040+
index_type: TableIndexType::Index,
10041+
for_clause: None,
10042+
},
10043+
TableIndexHints {
10044+
hint_type: TableIndexHintType::Ignore,
10045+
index_names: vec!["i2".into()],
10046+
index_type: TableIndexType::Index,
10047+
for_clause: Some(TableIndexHintForClause::OrderBy),
10048+
},
10049+
],
10050+
*index_hints
10051+
);
10052+
} else {
10053+
panic!("Expected TableFactor::Table");
10054+
}
10055+
supported_dialects.verified_stmt("SELECT * FROM t1 USE INDEX (i1) USE INDEX (i1, i1)");
10056+
supported_dialects.verified_stmt(
10057+
"SELECT * FROM t1 USE INDEX () IGNORE INDEX (i2) USE INDEX (i1) USE INDEX (i2)",
10058+
);
10059+
supported_dialects.verified_stmt("SELECT * FROM t1 FORCE INDEX FOR JOIN (i2)");
10060+
supported_dialects.verified_stmt("SELECT * FROM t1 IGNORE INDEX FOR JOIN (i2)");
10061+
supported_dialects.verified_stmt(
10062+
"SELECT * FROM t USE INDEX (index1) IGNORE INDEX FOR ORDER BY (index1) IGNORE INDEX FOR GROUP BY (index1) WHERE A = B",
10063+
);
10064+
10065+
// Test that dialects that don't support table hints will keep parsing the USE as table alias
10066+
let sql = "SELECT * FROM T USE LIMIT 1";
10067+
let unsupported_dialects = all_dialects_where(|d| !d.supports_table_hints());
10068+
let select = unsupported_dialects
10069+
.verified_only_select_with_canonical(sql, "SELECT * FROM T AS USE LIMIT 1");
10070+
assert_eq!(
10071+
select.from,
10072+
vec![TableWithJoins {
10073+
relation: TableFactor::Table {
10074+
name: ObjectName(vec![Ident::new("T")]),
10075+
alias: Some(TableAlias {
10076+
name: Ident::new("USE"),
10077+
columns: vec![],
10078+
}),
10079+
args: None,
10080+
with_hints: vec![],
10081+
version: None,
10082+
partitions: vec![],
10083+
with_ordinality: false,
10084+
json_path: None,
10085+
sample: None,
10086+
index_hints: vec![],
10087+
},
10088+
joins: vec![],
10089+
}]
10090+
);
10091+
}
10092+
1002810093
#[test]
1002910094
fn parse_pivot_unpivot_table() {
1003010095
let sql = concat!(

tests/sqlparser_mysql.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2900,21 +2900,6 @@ fn parse_lock_tables() {
29002900
mysql().verified_stmt("UNLOCK TABLES");
29012901
}
29022902

2903-
#[test]
2904-
fn parse_select_table_with_index_hints() {
2905-
mysql()
2906-
.verified_stmt("SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX FOR ORDER BY (i2) ORDER BY a");
2907-
mysql().verified_stmt("SELECT * FROM t1 USE INDEX (i1) USE INDEX (i1, i1)");
2908-
mysql().verified_stmt(
2909-
"SELECT * FROM t1 USE INDEX () IGNORE INDEX (i2) USE INDEX (i1) USE INDEX (i2)",
2910-
);
2911-
mysql().verified_stmt("SELECT * FROM t1 FORCE INDEX FOR JOIN (i2)");
2912-
mysql().verified_stmt("SELECT * FROM t1 IGNORE INDEX FOR JOIN (i2)");
2913-
mysql().verified_stmt(
2914-
"SELECT * FROM t USE INDEX (index1) IGNORE INDEX FOR ORDER BY (index1) IGNORE INDEX FOR GROUP BY (index1) WHERE A = B",
2915-
);
2916-
}
2917-
29182903
#[test]
29192904
fn parse_json_table() {
29202905
mysql().verified_only_select("SELECT * FROM JSON_TABLE('[[1, 2], [3, 4]]', '$[*]' COLUMNS(a INT PATH '$[0]', b INT PATH '$[1]')) AS t");

0 commit comments

Comments
 (0)