Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
10 changes: 9 additions & 1 deletion src/main/java/net/sf/jsqlparser/parser/AbstractJSqlParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@ public enum Dialect {
Feature.allowHashLineComments,
Feature.allowDoubleQuotedStrings), SQLSERVER(AdjacentStringLiterals.OFF,
Feature.allowSquareBracketQuotation), POSTGRESQL(
AdjacentStringLiterals.NEWLINE), H2, EXASOL;
AdjacentStringLiterals.NEWLINE), H2, EXASOL, BIGQUERY(
AdjacentStringLiterals.WHITESPACE,
Feature.allowDoubleQuotedStrings,
Feature.allowHashLineComments,
Feature.allowBackslashEscapeCharacter), DATABRICKS(
AdjacentStringLiterals.WHITESPACE,
Feature.allowDoubleQuotedStrings,
Feature.allowBackslashEscapeCharacter), SNOWFLAKE(
Feature.allowBackslashEscapeCharacter);

private final Set<Feature> lexerFeatures;
private final AdjacentStringLiterals adjacentStringLiterals;
Expand Down
2 changes: 1 addition & 1 deletion src/site/sphinx/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ Additionally there are Features to control the Parser's effort at the cost of th
.withBackslashEscapeCharacter(true)
);

Instead of turning the individual Parser Features on one by one, a ``Dialect`` preset selects the features of that database dialect: ``withDialect(Dialect.MYSQL)`` turns on ``withBackslashEscapeCharacter``, ``withHashLineComments`` and ``withDoubleQuotedStrings`` (MySQL and MariaDB syntax, the latter for the default sql_mode), ``withDialect(Dialect.SQLSERVER)`` turns on ``withSquareBracketQuotation``. ``withDialect(Dialect.POSTGRESQL)`` and ``withDialect(Dialect.ANSI_SQL)`` turn on the newline rule for adjacent String Literals. Features set explicitly after the dialect preset win over the preset.
Instead of turning the individual Parser Features on one by one, a ``Dialect`` preset selects the features of that database dialect: ``withDialect(Dialect.MYSQL)`` turns on ``withBackslashEscapeCharacter``, ``withHashLineComments`` and ``withDoubleQuotedStrings`` (MySQL and MariaDB syntax, the latter for the default sql_mode), ``withDialect(Dialect.SQLSERVER)`` turns on ``withSquareBracketQuotation``. ``withDialect(Dialect.POSTGRESQL)`` and ``withDialect(Dialect.ANSI_SQL)`` turn on the newline rule for adjacent String Literals. ``withDialect(Dialect.BIGQUERY)`` and ``withDialect(Dialect.DATABRICKS)`` turn on ``withDoubleQuotedStrings`` and ``withBackslashEscapeCharacter`` plus the any-whitespace rule for adjacent String Literals, the BigQuery preset additionally ``withHashLineComments``; ``withDialect(Dialect.SNOWFLAKE)`` turns on ``withBackslashEscapeCharacter`` only, keeping double quotes as quoted identifiers. Features set explicitly after the dialect preset win over the preset.

.. code-block:: java

Expand Down
51 changes: 46 additions & 5 deletions src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -641,19 +641,51 @@ public void testDoubleQuotedStringsFeature() throws Exception {
.parse("SELECT * FROM \"t\"", p -> p.withDoubleQuotedStrings(true)).toString());
}

@Test
public void testDialectPresetsWarehouses() throws Exception {
// BIGQUERY: double quoted strings, # line comments and backslash
// escapes (GoogleSQL "Lexical structure and syntax", identifiers are
// backticked), backticks stay unconditional
assertEquals("SELECT `col` FROM t WHERE a = 'x\\'yz' AND b = 42", CCJSqlParserUtil
.parse("SELECT `col` FROM t WHERE a = 'x\\'yz' AND b = 42#24",
p -> p.withDialect(AbstractJSqlParser.Dialect.BIGQUERY))
.toString());
// DATABRICKS: double quoted strings and backslash escapes (Spark
// "Literals"), `#` stays the #2507 operator
assertEquals("SELECT \"a\" FROM t WHERE x = 'it\\'s'", CCJSqlParserUtil
.parse("SELECT \"a\" FROM t WHERE x = 'it\\'s'",
p -> p.withDialect(AbstractJSqlParser.Dialect.DATABRICKS))
.toString());
assertEquals("SELECT 42 # 24", CCJSqlParserUtil.parse("SELECT 42 # 24",
p -> p.withDialect(AbstractJSqlParser.Dialect.DATABRICKS)).toString());
// SNOWFLAKE: backslash escape sequences ("String & binary data
// types"), `#` stays the operator
assertEquals("SELECT col FROM t WHERE a = 'x\\'yz'", CCJSqlParserUtil
.parse("SELECT col FROM t WHERE a = 'x\\'yz'",
p -> p.withDialect(AbstractJSqlParser.Dialect.SNOWFLAKE))
.toString());
assertEquals("SELECT 42 # 24", CCJSqlParserUtil.parse("SELECT 42 # 24",
p -> p.withDialect(AbstractJSqlParser.Dialect.SNOWFLAKE)).toString());
}

@Test
public void testDoubleQuotedStringsPreset() throws Exception {
// MYSQL and MARIADB presets carry the switch (default sql_mode reading)
// the string-default dialects: MYSQL and MARIADB (default sql_mode),
// BIGQUERY and DATABRICKS (string literals, identifiers are backticked)
for (AbstractJSqlParser.Dialect dialect : new AbstractJSqlParser.Dialect[] {
AbstractJSqlParser.Dialect.MYSQL, AbstractJSqlParser.Dialect.MARIADB}) {
AbstractJSqlParser.Dialect.MYSQL, AbstractJSqlParser.Dialect.MARIADB,
AbstractJSqlParser.Dialect.BIGQUERY, AbstractJSqlParser.Dialect.DATABRICKS}) {
PlainSelect select = (PlainSelect) ((Select) CCJSqlParserUtil
.parse("SELECT \"abc\"", p -> p.withDialect(dialect))).getSelectBody();
assertTrue(select.getSelectItems().get(0).getExpression() instanceof StringValue);
}
// the identifier-default dialects keep the quoted identifier reading
PlainSelect select = (PlainSelect) ((Select) CCJSqlParserUtil.parse("SELECT \"abc\"",
p -> p.withDialect(AbstractJSqlParser.Dialect.SQLSERVER))).getSelectBody();
assertTrue(select.getSelectItems().get(0).getExpression() instanceof Column);
for (AbstractJSqlParser.Dialect dialect : new AbstractJSqlParser.Dialect[] {
AbstractJSqlParser.Dialect.SQLSERVER, AbstractJSqlParser.Dialect.SNOWFLAKE}) {
PlainSelect select = (PlainSelect) ((Select) CCJSqlParserUtil.parse("SELECT \"abc\"",
p -> p.withDialect(dialect))).getSelectBody();
assertTrue(select.getSelectItems().get(0).getExpression() instanceof Column);
}
}

@Test
Expand Down Expand Up @@ -717,6 +749,15 @@ public void testAdjacentStringLiteralsWhitespace() throws Exception {
p -> p.withDoubleQuotedStrings(true).withAdjacentStringLiterals(
AbstractJSqlParser.AdjacentStringLiterals.WHITESPACE))
.toString());
// the BigQuery and Databricks presets carry it, the Snowflake preset
// does not (no adjacent-literal concatenation documented)
for (AbstractJSqlParser.Dialect dialect : new AbstractJSqlParser.Dialect[] {
AbstractJSqlParser.Dialect.BIGQUERY, AbstractJSqlParser.Dialect.DATABRICKS}) {
assertEquals("SELECT 'ab'", CCJSqlParserUtil.parse("SELECT 'a' 'b'",
p -> p.withDialect(dialect)).toString());
}
assertEquals("SELECT 'a' 'b'", CCJSqlParserUtil.parse("SELECT 'a' 'b'",
p -> p.withDialect(AbstractJSqlParser.Dialect.SNOWFLAKE)).toString());
}

@Test
Expand Down
Loading