diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 2d4c48c32..14411e519 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -22,14 +22,16 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'temurin' - name: Build with Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v2.4.2 with: arguments: build check # arguments: build check publish diff --git a/.github/workflows/sphinx.yml b/.github/workflows/sphinx.yml index 8ff3932aa..ad8bde188 100644 --- a/.github/workflows/sphinx.yml +++ b/.github/workflows/sphinx.yml @@ -2,8 +2,6 @@ name: Sphinx Pages on: push: branches: [ "master" ] - pull_request: - branches: [ "master" ] permissions: write-all jobs: @@ -21,9 +19,9 @@ jobs: ref: master fetch-depth: 0 - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v2.4.2 - name: Run build with Gradle Wrapper - run: gradle --no-build-cache clean xmldoc sphinx + run: FLOATING_TOC=false gradle --no-build-cache clean xmldoc sphinx - name: Deploy uses: actions/configure-pages@v2 - name: Upload artifact diff --git a/.gitignore b/.gitignore index 76f3c99dd..20db77d7c 100755 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ /src/site/sphinx/changelog.rst /src/site/sphinx/javadoc_stable.rst /src/site/sphinx/syntax_stable.rst +/src/site/sphinx/javadoc_snapshot.rst +/src/site/sphinx/syntax_snapshot.rst # Generated by javacc-maven-plugin /bin @@ -29,5 +31,3 @@ /nbproject/ /.gradle -/src/site/sphinx/javadoc_snapshot.rst -/src/site/sphinx/syntax_snapshot.rst diff --git a/README.md b/README.md index 61316bea2..f3449956a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# [JSqlParser (4.6 Stable or 4.7 Snapshot)](https://jsqlparser.github.io/JSqlParser) drawing +# [JSqlParser 4.7 Website](https://jsqlparser.github.io/JSqlParser) drawing ![Build Status](https://github.com/JSQLParser/JSqlParser/actions/workflows/maven.yml/badge.svg) @@ -54,9 +54,9 @@ Assertions.assertEquals("b", b.getColumnName()); **JSqlParser** aims to support the SQL standard as well as all major RDBMS. Any missing syntax or features can be added on demand. -| RDBMS | Statements | -|------------------------------------|-----------------------------------------| -| Oracle
MS SQL Server and Sybase
PostgreSQL
MySQL and MariaDB
DB2
H2 and HSQLDB and Derby
SQLite| `SELECT`
`INSERT`, `UPDATE`, `UPSERT`, `MERGE`
`DELETE`, `TRUNCATE TABLE`
`CREATE ...`, `ALTER ....`, `DROP ...`
`WITH ...` | +| RDBMS | Statements | +|-----------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| +| Oracle
MS SQL Server and Sybase
Postgres
MySQL and MariaDB
DB2
H2 and HSQLDB and Derby
SQLite | `SELECT`
`INSERT`, `UPDATE`, `UPSERT`, `MERGE`
`DELETE`, `TRUNCATE TABLE`
`CREATE ...`, `ALTER ....`, `DROP ...`
`WITH ...` | **JSqlParser** can also be used to create SQL Statements from Java Code with a fluent API (see [Samples](https://jsqlparser.github.io/JSqlParser/usage.html#build-a-sql-statements)). @@ -65,12 +65,11 @@ Assertions.assertEquals("b", b.getColumnName()); [**General SQL Parser**](http://www.sqlparser.com/features/introduce.php?utm_source=github-jsqlparser&utm_medium=text-general) looks pretty good, with extended SQL syntax (like PL/SQL and T-SQL) and java + .NET APIs. The tool is commercial (license available online), with a free download option. ## [Documentation](https://jsqlparser.github.io/JSqlParser) - -### [Samples](https://jsqlparser.github.io/JSqlParser/usage.html#parse-a-sql-statements) -### [Build Instructions](https://jsqlparser.github.io/JSqlParser/usage.html) -### [Contribution](https://jsqlparser.github.io/JSqlParser/contribution.html) -### [Change Log](https://jsqlparser.github.io/JSqlParser/changelog.html#latest-changes-since-jsqlparser-version) -### [Issues](https://github.com/JSQLParser/JSqlParser/issues) + 1. [Samples](https://jsqlparser.github.io/JSqlParser/usage.html#parse-a-sql-statements) + 2. [Build Instructions](https://jsqlparser.github.io/JSqlParser/usage.html) and [Maven Artifact](https://jsqlparser.github.io/JSqlParser/usage.html#build-dependencies) + 3. [Contribution](https://jsqlparser.github.io/JSqlParser/contribution.html) + 4. [Change Log](https://jsqlparser.github.io/JSqlParser/changelog.html#latest-changes-since-jsqlparser-version) + 5. [Issues](https://github.com/JSQLParser/JSqlParser/issues) ## License diff --git a/build.gradle b/build.gradle index d4cc92e13..4974164dc 100644 --- a/build.gradle +++ b/build.gradle @@ -62,7 +62,10 @@ def getVersion = { boolean considerSnapshot -> ? "${major}.${minor}.${patch}${snapshot}" : "${major}.${minor}${snapshot}" } -version = getVersion(true) + +// for publishing a release, call Gradle with Environment Variable RELEASE: +// RELEASE=true gradle JSQLParser:publish +version = getVersion( !System.getenv("RELEASE") ) group = 'com.github.jsqlparser' description = 'JSQLParser library' archivesBaseName = "JSQLParser" @@ -158,7 +161,7 @@ tasks.register('xmldoc', Javadoc) { options.doclet = "com.github.markusbernhardt.xmldoclet.XmlDoclet" title = "API $version" options.addBooleanOption("rst", true) - options.addBooleanOption("withFloatingToc", true) + options.addBooleanOption("withFloatingToc", Boolean.parseBoolean(System.getenv().getOrDefault("FLOATING_TOC", "true"))) options.addStringOption("basePackage", "net.sf.jsqlparser") options.addStringOption("filename", outFile.getName()) @@ -431,6 +434,11 @@ xslt { dependsOn(renderRR) stylesheet 'src/main/resources/rr/xhtml2rst.xsl' + parameters ( + "withFloatingToc": System.getenv().getOrDefault("FLOATING_TOC", "true"), + "isSnapshot": Boolean.toString(version.endsWith("-SNAPSHOT")) + ) + // Transform every .xml file in the "input" directory. input "$buildDir/rr/JSqlParserCC.xhtml" output outFile @@ -478,7 +486,7 @@ tasks.register('sphinx', Exec) { } publish { - dependsOn(check) + dependsOn(check, gitChangelogTask, renderRR, xslt, updateKeywords, xmldoc) } publishing { @@ -593,4 +601,5 @@ tasks.register('upload') { } } } +upload.dependsOn(check, assemble, gitChangelogTask, renderRR, xslt, updateKeywords, xmldoc) diff --git a/config/pmd/ruleset.xml b/config/pmd/ruleset.xml index fdfa1169d..6b8c681a6 100644 --- a/config/pmd/ruleset.xml +++ b/config/pmd/ruleset.xml @@ -77,7 +77,12 @@ under the License. - + + + + + + diff --git a/gradle.properties b/gradle.properties index f1dda8d41..522c7558e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,3 +10,8 @@ org.gradle.parallel=true # Enable configure on demand. org.gradle.configureondemand=true +# see https://docs.gradle.org/current/userguide/upgrading_version_8.html#xml_parsing_now_requires_recent_parsers +systemProp.javax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl +systemProp.javax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl +systemProp.javax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index ccebba771..7f93135c4 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bdc9a83b1..3fa8f862f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 79a61d421..0adc8e1a5 100755 --- a/gradlew +++ b/gradlew @@ -83,10 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -197,6 +198,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in diff --git a/pom.xml b/pom.xml index 60b36c8a7..da8534c2e 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.github.jsqlparser jsqlparser - 4.7 + 4.8 JSQLParser library 2004 @@ -29,7 +29,7 @@ net.java.dev.javacc javacc - 7.0.12 + 7.0.13 test @@ -95,11 +95,11 @@ sonatype-nexus-staging - https://oss.sonatype.org/service/local/staging/deploy/maven2 + https://oss.sonatype.org/service/local/staging/deploy/maven2/ sonatype-nexus-snapshots - https://oss.sonatype.org/content/repositories/snapshots + https://oss.sonatype.org/content/repositories/snapshots/ @@ -107,7 +107,7 @@ scm:git:https://github.com/JSQLParser/JSqlParser.git scm:git:ssh://git@github.com:JSQLParser/JSqlParser.git https://github.com/JSQLParser/JSqlParser.git - jsqlparser-4.7 + jsqlparser-4.8 @@ -230,7 +230,7 @@ net.java.dev.javacc javacc - 7.0.12 + 7.0.13 @@ -371,7 +371,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M7 + 3.2.3 false @@ -379,7 +379,7 @@ org.jacoco jacoco-maven-plugin - 0.8.8 + 0.8.10 diff --git a/src/main/java/net/sf/jsqlparser/expression/AnalyticExpression.java b/src/main/java/net/sf/jsqlparser/expression/AnalyticExpression.java index 75e53c0fa..fc7d7d466 100644 --- a/src/main/java/net/sf/jsqlparser/expression/AnalyticExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/AnalyticExpression.java @@ -53,7 +53,7 @@ public AnalyticExpression(Function function) { unique = function.isUnique(); funcOrderBy = function.getOrderByElements(); - ExpressionList list = function.getParameters(); + ExpressionList list = function.getParameters(); if (list != null) { if (list.getExpressions().size() > 3) { throw new IllegalArgumentException( diff --git a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java index b1bc3ffe5..d0fe61a91 100644 --- a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java +++ b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java @@ -25,6 +25,9 @@ import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.conditional.XorExpression; import net.sf.jsqlparser.expression.operators.relational.Between; +import net.sf.jsqlparser.expression.operators.relational.ContainedBy; +import net.sf.jsqlparser.expression.operators.relational.Contains; +import net.sf.jsqlparser.expression.operators.relational.DoubleAnd; import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; @@ -45,6 +48,8 @@ import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo; import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator; import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression; +import net.sf.jsqlparser.expression.operators.relational.TSQLLeftJoin; +import net.sf.jsqlparser.expression.operators.relational.TSQLRightJoin; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.select.AllColumns; import net.sf.jsqlparser.statement.select.AllTableColumns; @@ -125,6 +130,12 @@ public interface ExpressionVisitor { void visit(NotEqualsTo notEqualsTo); + void visit(DoubleAnd doubleAnd); + + void visit(Contains contains); + + void visit(ContainedBy containedBy); + void visit(ParenthesedSelect selectBody); void visit(Column tableColumn); @@ -230,4 +241,9 @@ public interface ExpressionVisitor { void visit(TrimFunction trimFunction); void visit(RangeExpression rangeExpression); + + void visit(TSQLLeftJoin tsqlLeftJoin); + + void visit(TSQLRightJoin tsqlRightJoin); + } diff --git a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java index 1da72c3d2..a93efedb5 100644 --- a/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java +++ b/src/main/java/net/sf/jsqlparser/expression/ExpressionVisitorAdapter.java @@ -25,6 +25,9 @@ import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.conditional.XorExpression; import net.sf.jsqlparser.expression.operators.relational.Between; +import net.sf.jsqlparser.expression.operators.relational.ContainedBy; +import net.sf.jsqlparser.expression.operators.relational.Contains; +import net.sf.jsqlparser.expression.operators.relational.DoubleAnd; import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; @@ -45,6 +48,7 @@ import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo; import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator; import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression; +import net.sf.jsqlparser.expression.operators.relational.*; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.select.AllColumns; import net.sf.jsqlparser.statement.select.AllTableColumns; @@ -255,6 +259,21 @@ public void visit(NotEqualsTo expr) { visitBinaryExpression(expr); } + @Override + public void visit(DoubleAnd expr) { + visitBinaryExpression(expr); + } + + @Override + public void visit(Contains expr) { + visitBinaryExpression(expr); + } + + @Override + public void visit(ContainedBy expr) { + visitBinaryExpression(expr); + } + @Override public void visit(Column column) { @@ -652,4 +671,15 @@ public void visit(RangeExpression rangeExpression) { rangeExpression.getStartExpression().accept(this); rangeExpression.getEndExpression().accept(this); } + + @Override + public void visit(TSQLLeftJoin tsqlLeftJoin) { + visitBinaryExpression(tsqlLeftJoin); + } + + @Override + public void visit(TSQLRightJoin tsqlRightJoin) { + visitBinaryExpression(tsqlRightJoin); + } + } diff --git a/src/main/java/net/sf/jsqlparser/expression/Function.java b/src/main/java/net/sf/jsqlparser/expression/Function.java index 70066fc07..9a7c2d9d9 100644 --- a/src/main/java/net/sf/jsqlparser/expression/Function.java +++ b/src/main/java/net/sf/jsqlparser/expression/Function.java @@ -24,8 +24,8 @@ public class Function extends ASTNodeAccessImpl implements Expression { private List nameparts; - private ExpressionList parameters; - private NamedExpressionList namedParameters; + private ExpressionList parameters; + private NamedExpressionList namedParameters; private boolean allColumns = false; private boolean distinct = false; private boolean unique = false; @@ -58,6 +58,11 @@ public Function withName(String name) { return this; } + public Function withName(List nameparts) { + this.nameparts = nameparts; + return this; + } + public void setName(List string) { nameparts = string; } @@ -115,11 +120,19 @@ public void setUnique(boolean b) { * * @return the list of parameters of the function (if any, else null) */ - public ExpressionList getParameters() { + public ExpressionList getParameters() { return parameters; } - public void setParameters(ExpressionList list) { + public void setParameters(Expression... expressions) { + if (expressions.length == 1 && expressions[0] instanceof ExpressionList) { + parameters = (ExpressionList) expressions[0]; + } else { + parameters = new ExpressionList<>(expressions); + } + } + + public void setParameters(ExpressionList list) { parameters = list; } @@ -132,7 +145,7 @@ public NamedExpressionList getNamedParameters() { return namedParameters; } - public void setNamedParameters(NamedExpressionList list) { + public void setNamedParameters(NamedExpressionList list) { namedParameters = list; } @@ -267,16 +280,16 @@ public Function withIgnoreNulls(boolean ignoreNulls) { return this; } - public Function withParameters(ExpressionList parameters) { + public Function withParameters(ExpressionList parameters) { this.setParameters(parameters); return this; } public Function withParameters(Expression... parameters) { - return withParameters(new ExpressionList(parameters)); + return withParameters(new ExpressionList<>(parameters)); } - public Function withNamedParameters(NamedExpressionList namedParameters) { + public Function withNamedParameters(NamedExpressionList namedParameters) { this.setNamedParameters(namedParameters); return this; } diff --git a/src/main/java/net/sf/jsqlparser/expression/JsonExpression.java b/src/main/java/net/sf/jsqlparser/expression/JsonExpression.java index 5d6aa794c..9fe2811cf 100644 --- a/src/main/java/net/sf/jsqlparser/expression/JsonExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/JsonExpression.java @@ -9,16 +9,31 @@ */ package net.sf.jsqlparser.expression; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; + +import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Collection; import java.util.List; - -import net.sf.jsqlparser.parser.ASTNodeAccessImpl; +import java.util.Map; public class JsonExpression extends ASTNodeAccessImpl implements Expression { private Expression expr; - private List idents = new ArrayList(); - private List operators = new ArrayList(); + private final List> idents = new ArrayList<>(); + + public JsonExpression() { + + } + + public JsonExpression(Expression expr) { + this.expr = expr; + } + + public JsonExpression(Expression expr, List> idents) { + this.expr = expr; + this.idents.addAll(idents); + } @Override public void accept(ExpressionVisitor expressionVisitor) { @@ -34,24 +49,46 @@ public void setExpression(Expression expr) { } public void addIdent(String ident, String operator) { - idents.add(ident); - operators.add(operator); + idents.add(new AbstractMap.SimpleEntry<>(ident, operator)); } - public List getIdents() { + public void addAllIdents(Collection> idents) { + this.idents.addAll(idents); + } + + public List> getIdentList() { return idents; } + public Map.Entry getIdent(int index) { + return idents.get(index); + } + + @Deprecated + public List getIdents() { + ArrayList l = new ArrayList<>(); + for (Map.Entry ident : idents) { + l.add(ident.getKey()); + } + + return l; + } + + @Deprecated public List getOperators() { - return operators; + ArrayList l = new ArrayList<>(); + for (Map.Entry ident : idents) { + l.add(ident.getValue()); + } + return l; } @Override public String toString() { StringBuilder b = new StringBuilder(); b.append(expr.toString()); - for (int i = 0; i < idents.size(); i++) { - b.append(operators.get(i)).append(idents.get(i)); + for (Map.Entry ident : idents) { + b.append(ident.getValue()).append(ident.getKey()); } return b.toString(); } diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/ContainedBy.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/ContainedBy.java new file mode 100644 index 000000000..b0a5abcbb --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/ContainedBy.java @@ -0,0 +1,25 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2023 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.expression.operators.relational; + +import net.sf.jsqlparser.expression.ExpressionVisitor; + +public class ContainedBy extends ComparisonOperator { + + public ContainedBy() { + super("<&"); + } + + @Override + public void accept(ExpressionVisitor expressionVisitor) { + expressionVisitor.visit(this); + } +} + diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/Contains.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/Contains.java new file mode 100644 index 000000000..c362dc2be --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/Contains.java @@ -0,0 +1,25 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2023 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.expression.operators.relational; + +import net.sf.jsqlparser.expression.ExpressionVisitor; + +public class Contains extends ComparisonOperator { + + public Contains() { + super("&>"); + } + + @Override + public void accept(ExpressionVisitor expressionVisitor) { + expressionVisitor.visit(this); + } +} + diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/DoubleAnd.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/DoubleAnd.java new file mode 100644 index 000000000..c060cbc52 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/DoubleAnd.java @@ -0,0 +1,24 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2023 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.expression.operators.relational; + +import net.sf.jsqlparser.expression.ExpressionVisitor; + +public class DoubleAnd extends ComparisonOperator { + + public DoubleAnd() { + super("&&"); + } + + @Override + public void accept(ExpressionVisitor expressionVisitor) { + expressionVisitor.visit(this); + } +} diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/InExpression.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/InExpression.java index e359c693a..af6ad913d 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/InExpression.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/InExpression.java @@ -17,6 +17,7 @@ public class InExpression extends ASTNodeAccessImpl implements Expression, SupportsOldOracleJoinSyntax { private Expression leftExpression; + private boolean global = false; private boolean not = false; private Expression rightExpression; private int oldOracleJoinSyntax = NO_ORACLE_JOIN; @@ -56,6 +57,15 @@ public final void setLeftExpression(Expression expression) { leftExpression = expression; } + public boolean isGlobal() { + return global; + } + + public InExpression setGlobal(boolean b) { + global = b; + return this; + } + public boolean isNot() { return not; } @@ -87,6 +97,9 @@ public String toString() { statementBuilder.append(getLeftExpressionString()); statementBuilder.append(" "); + if (global) { + statementBuilder.append("GLOBAL "); + } if (not) { statementBuilder.append("NOT "); } @@ -124,6 +137,11 @@ public InExpression withOraclePriorPosition(int priorPosition) { return this; } + public InExpression withGlobal(boolean global) { + this.setGlobal(global); + return this; + } + public InExpression withNot(boolean not) { this.setNot(not); return this; diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLLeftJoin.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLLeftJoin.java new file mode 100644 index 000000000..e654bab2d --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLLeftJoin.java @@ -0,0 +1,24 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2019 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.expression.operators.relational; + +import net.sf.jsqlparser.expression.ExpressionVisitor; + +public class TSQLLeftJoin extends ComparisonOperator { + + public TSQLLeftJoin() { + super("*="); + } + + @Override + public void accept(ExpressionVisitor expressionVisitor) { + expressionVisitor.visit(this); + } +} diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLRightJoin.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLRightJoin.java new file mode 100644 index 000000000..a38ad4a9a --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/TSQLRightJoin.java @@ -0,0 +1,24 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2019 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.expression.operators.relational; + +import net.sf.jsqlparser.expression.ExpressionVisitor; + +public class TSQLRightJoin extends ComparisonOperator { + + public TSQLRightJoin() { + super("=*"); + } + + @Override + public void accept(ExpressionVisitor expressionVisitor) { + expressionVisitor.visit(this); + } +} diff --git a/src/main/java/net/sf/jsqlparser/parser/ParserKeywordsUtils.java b/src/main/java/net/sf/jsqlparser/parser/ParserKeywordsUtils.java index 9306e01da..6aa5686c9 100644 --- a/src/main/java/net/sf/jsqlparser/parser/ParserKeywordsUtils.java +++ b/src/main/java/net/sf/jsqlparser/parser/ParserKeywordsUtils.java @@ -45,54 +45,104 @@ public class ParserKeywordsUtils { // Classification follows http://www.h2database.com/html/advanced.html#keywords public final static Object[][] ALL_RESERVED_KEYWORDS = { - {"ABSENT", RESTRICTED_JSQLPARSER}, {"ALL", RESTRICTED_SQL2016}, - {"AND", RESTRICTED_SQL2016}, {"ANY", RESTRICTED_JSQLPARSER}, {"AS", RESTRICTED_SQL2016}, - {"BETWEEN", RESTRICTED_SQL2016}, {"BOTH", RESTRICTED_SQL2016}, - {"CASEWHEN", RESTRICTED_ALIAS}, {"CHECK", RESTRICTED_SQL2016}, - {"CONNECT", RESTRICTED_ALIAS}, {"CONNECT_BY_ROOT", RESTRICTED_JSQLPARSER}, - {"CONSTRAINT", RESTRICTED_SQL2016}, {"CREATE", RESTRICTED_ALIAS}, - {"CROSS", RESTRICTED_SQL2016}, {"CURRENT", RESTRICTED_JSQLPARSER}, - {"DISTINCT", RESTRICTED_SQL2016}, {"DOUBLE", RESTRICTED_ALIAS}, - {"ELSE", RESTRICTED_JSQLPARSER}, {"EXCEPT", RESTRICTED_SQL2016}, - {"EXISTS", RESTRICTED_SQL2016}, {"FETCH", RESTRICTED_SQL2016}, - {"FINAL", RESTRICTED_JSQLPARSER}, {"FOR", RESTRICTED_SQL2016}, - {"FORCE", RESTRICTED_SQL2016}, {"FOREIGN", RESTRICTED_SQL2016}, - {"FROM", RESTRICTED_SQL2016}, {"FULL", RESTRICTED_SQL2016}, - {"GROUP", RESTRICTED_SQL2016}, {"GROUPING", RESTRICTED_ALIAS}, + {"ABSENT", RESTRICTED_JSQLPARSER}, + {"ALL", RESTRICTED_SQL2016}, + {"AND", RESTRICTED_SQL2016}, + {"ANY", RESTRICTED_JSQLPARSER}, + {"AS", RESTRICTED_SQL2016}, + {"BETWEEN", RESTRICTED_SQL2016}, + {"BOTH", RESTRICTED_SQL2016}, + {"CASEWHEN", RESTRICTED_ALIAS}, + {"CHECK", RESTRICTED_SQL2016}, + {"CONNECT", RESTRICTED_ALIAS}, + {"CONNECT_BY_ROOT", RESTRICTED_JSQLPARSER}, + {"CONSTRAINT", RESTRICTED_SQL2016}, + {"CREATE", RESTRICTED_ALIAS}, + {"CROSS", RESTRICTED_SQL2016}, + {"CURRENT", RESTRICTED_JSQLPARSER}, + {"DISTINCT", RESTRICTED_SQL2016}, + {"DOUBLE", RESTRICTED_ALIAS}, + {"ELSE", RESTRICTED_JSQLPARSER}, + {"EXCEPT", RESTRICTED_SQL2016}, + {"EXISTS", RESTRICTED_SQL2016}, + {"FETCH", RESTRICTED_SQL2016}, + {"FINAL", RESTRICTED_JSQLPARSER}, + {"FOR", RESTRICTED_SQL2016}, + {"FORCE", RESTRICTED_SQL2016}, + {"FOREIGN", RESTRICTED_SQL2016}, + {"FROM", RESTRICTED_SQL2016}, + {"FULL", RESTRICTED_SQL2016}, + {"GLOBAL", RESTRICTED_ALIAS}, + {"GROUP", RESTRICTED_SQL2016}, + {"GROUPING", RESTRICTED_ALIAS}, {"QUALIFY", RESTRICTED_ALIAS}, - {"HAVING", RESTRICTED_SQL2016}, {"IF", RESTRICTED_SQL2016}, {"IIF", RESTRICTED_ALIAS}, - {"IGNORE", RESTRICTED_ALIAS}, {"ILIKE", RESTRICTED_SQL2016}, {"IN", RESTRICTED_SQL2016}, - {"INNER", RESTRICTED_SQL2016}, {"INTERSECT", RESTRICTED_SQL2016}, - {"INTERVAL", RESTRICTED_SQL2016}, {"INTO", RESTRICTED_JSQLPARSER}, - {"IS", RESTRICTED_SQL2016}, {"JOIN", RESTRICTED_JSQLPARSER}, - {"LATERAL", RESTRICTED_SQL2016}, {"LEFT", RESTRICTED_SQL2016}, - {"LIKE", RESTRICTED_SQL2016}, {"LIMIT", RESTRICTED_SQL2016}, - {"MINUS", RESTRICTED_SQL2016}, {"NATURAL", RESTRICTED_SQL2016}, - {"NOCYCLE", RESTRICTED_JSQLPARSER}, {"NOT", RESTRICTED_SQL2016}, - {"NULL", RESTRICTED_SQL2016}, {"OFFSET", RESTRICTED_SQL2016}, - {"ON", RESTRICTED_SQL2016}, {"ONLY", RESTRICTED_JSQLPARSER}, - {"OPTIMIZE", RESTRICTED_ALIAS}, {"OR", RESTRICTED_SQL2016}, - {"ORDER", RESTRICTED_SQL2016}, {"OUTER", RESTRICTED_JSQLPARSER}, - {"OUTPUT", RESTRICTED_JSQLPARSER}, {"OPTIMIZE ", RESTRICTED_JSQLPARSER}, - {"PIVOT", RESTRICTED_JSQLPARSER}, {"PROCEDURE", RESTRICTED_ALIAS}, - {"PUBLIC", RESTRICTED_ALIAS}, {"RECURSIVE", RESTRICTED_SQL2016}, - {"REGEXP", RESTRICTED_SQL2016}, {"RETURNING", RESTRICTED_JSQLPARSER}, - {"RIGHT", RESTRICTED_SQL2016}, {"SAMPLE", RESTRICTED_ALIAS}, {"SEL", RESTRICTED_ALIAS}, + {"HAVING", RESTRICTED_SQL2016}, + {"IF", RESTRICTED_SQL2016}, + {"IIF", RESTRICTED_ALIAS}, + {"IGNORE", RESTRICTED_ALIAS}, + {"ILIKE", RESTRICTED_SQL2016}, + {"IN", RESTRICTED_SQL2016}, + {"INNER", RESTRICTED_SQL2016}, + {"INTERSECT", RESTRICTED_SQL2016}, + {"INTERVAL", RESTRICTED_SQL2016}, + {"INTO", RESTRICTED_JSQLPARSER}, + {"IS", RESTRICTED_SQL2016}, + {"JOIN", RESTRICTED_JSQLPARSER}, + {"LATERAL", RESTRICTED_SQL2016}, + {"LEFT", RESTRICTED_SQL2016}, + {"LIKE", RESTRICTED_SQL2016}, + {"LIMIT", RESTRICTED_SQL2016}, + {"MINUS", RESTRICTED_SQL2016}, + {"NATURAL", RESTRICTED_SQL2016}, + {"NOCYCLE", RESTRICTED_JSQLPARSER}, + {"NOT", RESTRICTED_SQL2016}, + {"NULL", RESTRICTED_SQL2016}, + {"OFFSET", RESTRICTED_SQL2016}, + {"ON", RESTRICTED_SQL2016}, + {"ONLY", RESTRICTED_JSQLPARSER}, + {"OPTIMIZE", RESTRICTED_ALIAS}, + {"OR", RESTRICTED_SQL2016}, + {"ORDER", RESTRICTED_SQL2016}, + {"OUTER", RESTRICTED_JSQLPARSER}, + {"OUTPUT", RESTRICTED_JSQLPARSER}, + {"OPTIMIZE ", RESTRICTED_JSQLPARSER}, + {"PIVOT", RESTRICTED_JSQLPARSER}, + {"PROCEDURE", RESTRICTED_ALIAS}, + {"PUBLIC", RESTRICTED_ALIAS}, + {"RECURSIVE", RESTRICTED_SQL2016}, + {"REGEXP", RESTRICTED_SQL2016}, + {"RETURNING", RESTRICTED_JSQLPARSER}, + {"RIGHT", RESTRICTED_SQL2016}, + {"SAMPLE", RESTRICTED_ALIAS}, + {"SEL", RESTRICTED_ALIAS}, {"SELECT", RESTRICTED_ALIAS}, - {"SEMI", RESTRICTED_JSQLPARSER}, {"SET", RESTRICTED_JSQLPARSER}, - {"SOME", RESTRICTED_JSQLPARSER}, {"START", RESTRICTED_JSQLPARSER}, - {"TABLES", RESTRICTED_ALIAS}, {"TOP", RESTRICTED_SQL2016}, - {"TRAILING", RESTRICTED_SQL2016}, {"UNBOUNDED", RESTRICTED_JSQLPARSER}, - {"UNION", RESTRICTED_SQL2016}, {"UNIQUE", RESTRICTED_SQL2016}, - {"UNPIVOT", RESTRICTED_JSQLPARSER}, {"USE", RESTRICTED_JSQLPARSER}, - {"USING", RESTRICTED_SQL2016}, {"SQL_CACHE", RESTRICTED_JSQLPARSER}, - {"SQL_CALC_FOUND_ROWS", RESTRICTED_JSQLPARSER}, {"SQL_NO_CACHE", RESTRICTED_JSQLPARSER}, - {"STRAIGHT_JOIN", RESTRICTED_JSQLPARSER}, {"TABLESAMPLE", RESTRICTED_ALIAS}, + {"SEMI", RESTRICTED_JSQLPARSER}, + {"SET", RESTRICTED_JSQLPARSER}, + {"SOME", RESTRICTED_JSQLPARSER}, + {"START", RESTRICTED_JSQLPARSER}, + {"TABLES", RESTRICTED_ALIAS}, + {"TOP", RESTRICTED_SQL2016}, + {"TRAILING", RESTRICTED_SQL2016}, + {"UNBOUNDED", RESTRICTED_JSQLPARSER}, + {"UNION", RESTRICTED_SQL2016}, + {"UNIQUE", RESTRICTED_SQL2016}, + {"UNPIVOT", RESTRICTED_JSQLPARSER}, + {"USE", RESTRICTED_JSQLPARSER}, + {"USING", RESTRICTED_SQL2016}, + {"SQL_CACHE", RESTRICTED_JSQLPARSER}, + {"SQL_CALC_FOUND_ROWS", RESTRICTED_JSQLPARSER}, + {"SQL_NO_CACHE", RESTRICTED_JSQLPARSER}, + {"STRAIGHT_JOIN", RESTRICTED_JSQLPARSER}, + {"TABLESAMPLE", RESTRICTED_ALIAS}, {"VALUE", RESTRICTED_JSQLPARSER}, - {"VALUES", RESTRICTED_SQL2016}, {"VARYING", RESTRICTED_JSQLPARSER}, - {"WHEN", RESTRICTED_SQL2016}, {"WHERE", RESTRICTED_SQL2016}, - {"WINDOW", RESTRICTED_SQL2016}, {"WITH", RESTRICTED_SQL2016}, - {"XOR", RESTRICTED_JSQLPARSER}, {"XMLSERIALIZE", RESTRICTED_JSQLPARSER} + {"VALUES", RESTRICTED_SQL2016}, + {"VARYING", RESTRICTED_JSQLPARSER}, + {"WHEN", RESTRICTED_SQL2016}, + {"WHERE", RESTRICTED_SQL2016}, + {"WINDOW", RESTRICTED_SQL2016}, + {"WITH", RESTRICTED_SQL2016}, + {"XOR", RESTRICTED_JSQLPARSER}, + {"XMLSERIALIZE", RESTRICTED_JSQLPARSER}, // add keywords from the composite token definitions: // tk= | tk= | tk= @@ -100,23 +150,26 @@ public class ParserKeywordsUtils { // simple keywords // @todo: figure out a way to remove these composite tokens, as they do more harm than // good - , {"SEL", RESTRICTED_JSQLPARSER}, {"SELECT", RESTRICTED_JSQLPARSER} - - , {"DATE", RESTRICTED_JSQLPARSER}, {"TIME", RESTRICTED_JSQLPARSER}, - {"TIMESTAMP", RESTRICTED_JSQLPARSER} - - , {"YEAR", RESTRICTED_JSQLPARSER}, {"MONTH", RESTRICTED_JSQLPARSER}, - {"DAY", RESTRICTED_JSQLPARSER}, {"HOUR", RESTRICTED_JSQLPARSER}, - {"MINUTE", RESTRICTED_JSQLPARSER}, {"SECOND", RESTRICTED_JSQLPARSER} - - , {"SUBSTR", RESTRICTED_JSQLPARSER}, {"SUBSTRING", RESTRICTED_JSQLPARSER}, - {"TRIM", RESTRICTED_JSQLPARSER}, {"POSITION", RESTRICTED_JSQLPARSER}, - {"OVERLAY", RESTRICTED_JSQLPARSER} - - , {"NEXTVAL", RESTRICTED_JSQLPARSER} + {"SEL", RESTRICTED_JSQLPARSER}, + {"SELECT", RESTRICTED_JSQLPARSER}, + {"DATE", RESTRICTED_JSQLPARSER}, + {"TIME", RESTRICTED_JSQLPARSER}, + {"TIMESTAMP", RESTRICTED_JSQLPARSER}, + {"YEAR", RESTRICTED_JSQLPARSER}, + {"MONTH", RESTRICTED_JSQLPARSER}, + {"DAY", RESTRICTED_JSQLPARSER}, + {"HOUR", RESTRICTED_JSQLPARSER}, + {"MINUTE", RESTRICTED_JSQLPARSER}, + {"SECOND", RESTRICTED_JSQLPARSER}, + {"SUBSTR", RESTRICTED_JSQLPARSER}, + {"SUBSTRING", RESTRICTED_JSQLPARSER}, + {"TRIM", RESTRICTED_JSQLPARSER}, + {"POSITION", RESTRICTED_JSQLPARSER}, + {"OVERLAY", RESTRICTED_JSQLPARSER}, + {"NEXTVAL", RESTRICTED_COLUMN}, // @todo: Object Names should not start with Hex-Prefix, we shall not find that Token - , {"0x", RESTRICTED_JSQLPARSER} + {"0x", RESTRICTED_JSQLPARSER} }; @SuppressWarnings({"PMD.ExcessiveMethodLength"}) @@ -126,8 +179,7 @@ public static List getReservedKeywords(int restriction) { int value = (int) data[1]; // test if bit is not set - if ((value & restriction) == restriction - || (restriction & value) == value) { + if ((value & restriction) == restriction || (restriction & value) == value) { keywords.add((String) data[0]); } } @@ -136,7 +188,6 @@ public static List getReservedKeywords(int restriction) { } /** - * * @param args with: Grammar File, Keyword Documentation File * @throws Exception */ @@ -164,7 +215,7 @@ public static void main(String[] args) throws Exception { public static TreeSet getAllKeywordsUsingRegex(File file) throws IOException { Pattern tokenBlockPattern = Pattern.compile( - "TOKEN\\s*:\\s*(?:/\\*.*\\*/*)\\n\\{(?:[^\\}\\{]+|\\{(?:[^\\}\\{]+|\\{[^\\}\\{]*\\})*\\})*\\}", + "TOKEN\\s*:\\s*(?:/\\*.*\\*/*)(?:\\r?\\n|\\r)\\{(?:[^\\}\\{]+|\\{(?:[^\\}\\{]+|\\{[^\\}\\{]*\\})*\\})*\\}", Pattern.MULTILINE); Pattern tokenStringValuePattern = Pattern.compile("\\\"(\\w{2,})\\\"", Pattern.MULTILINE); @@ -213,9 +264,7 @@ public static void buildGrammarForRelObjectNameWithoutValue(File file) throws Ex builder.append(" | tk=\"").append(keyword).append("\""); } - builder.append(" )\n" - + " { return tk.image; }\n" - + "}"); + builder.append(" )\n" + " { return tk.image; }\n" + "}"); replaceInFile(file, methodBlockPattern, builder.toString()); } @@ -244,9 +293,7 @@ public static void buildGrammarForRelObjectName(File file) throws Exception { builder.append(" | tk=\"").append(keyword).append("\""); } - builder.append(" )\n" - + " { return tk!=null ? tk.image : result; }\n" - + "}"); + builder.append(" )\n" + " { return tk!=null ? tk.image : result; }\n" + "}"); // @todo: Needs fine-tuning, we are not replacing this part yet // replaceInFile(file, pattern, builder.toString()); @@ -267,9 +314,7 @@ private static void replaceInFile(File file, Pattern pattern, String replacement } public static String rightPadding(String input, char ch, int length) { - return String - .format("%" + (-length) + "s", input) - .replace(' ', ch); + return String.format("%" + (-length) + "s", input).replace(' ', ch); } public static void writeKeywordsDocumentationFile(File file) throws IOException { @@ -293,13 +338,15 @@ public static void writeKeywordsDocumentationFile(File file) throws IOException int value = (int) keywordDefinition[1]; int restriction = RESTRICTED_JSQLPARSER; - String s = - (value & restriction) == restriction || (restriction & value) == value ? "Yes" - : ""; + String s = (value & restriction) == restriction || (restriction & value) == value + ? "Yes" + : ""; builder.append(rightPadding(s, ' ', 11)).append(" | "); restriction = RESTRICTED_SQL2016; - s = (value & restriction) == restriction || (restriction & value) == value ? "Yes" : ""; + s = (value & restriction) == restriction || (restriction & value) == value + ? "Yes" + : ""; builder.append(rightPadding(s, ' ', 9)).append(" | "); builder.append("\n"); diff --git a/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java b/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java index 7d7e94a72..011919338 100644 --- a/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java +++ b/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java @@ -44,6 +44,7 @@ import net.sf.jsqlparser.statement.execute.Execute; import net.sf.jsqlparser.statement.grant.Grant; import net.sf.jsqlparser.statement.merge.Merge; +import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement; import net.sf.jsqlparser.statement.select.Fetch; import net.sf.jsqlparser.statement.select.First; import net.sf.jsqlparser.statement.select.KSQLWindow; @@ -243,6 +244,22 @@ public enum Feature { * "FOR UPDATE" */ selectForUpdate, + + /** + * "FOR SHARE" + */ + selectForShare, + + /** + * "FOR KEY SHARE" + */ + selectForKeyShare, + + /** + * "NO KEY UPDATE" + */ + selectForNoKeyUpdate, + /** * "FOR UPDATE OF table" */ @@ -305,6 +322,11 @@ public enum Feature { */ values, + /** + * SQL "TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]“ + */ + tableStatement, + /** * SQL "UPDATE" statement is allowed * @@ -391,6 +413,14 @@ public enum Feature { * @see AlterView */ alterView, + + /** + * SQL "REFRESH MATERIALIZED VIEW" statement is allowed + * + * @see RefreshMaterializedViewStatement + */ + refreshMaterializedView, refreshMaterializedWithDataView, refreshMaterializedWithNoDataView, + /** * SQL "REPLACE VIEW" statement is allowed * @@ -474,6 +504,12 @@ public enum Feature { * SQL "CREATE MATERIALIZED VIEW" statement is allowed */ createViewMaterialized, + + /** + * SQL "CREATE VIEW(x comment 'x', y comment 'y') comment 'view'" statement is allowed + */ + createViewWithComment, + /** * SQL "CREATE TABLE" statement is allowed * @@ -557,6 +593,14 @@ public enum Feature { * @see DescribeStatement */ describe, + + /** + * SQL "DESC" statement is allowed + * + * @see DescribeStatement + */ + desc, + /** * SQL "EXPLAIN" statement is allowed * diff --git a/src/main/java/net/sf/jsqlparser/schema/Column.java b/src/main/java/net/sf/jsqlparser/schema/Column.java index 684e0faf5..3f7721ca3 100644 --- a/src/main/java/net/sf/jsqlparser/schema/Column.java +++ b/src/main/java/net/sf/jsqlparser/schema/Column.java @@ -9,13 +9,12 @@ */ package net.sf.jsqlparser.schema; +import java.util.List; import net.sf.jsqlparser.expression.ArrayConstructor; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.ExpressionVisitor; import net.sf.jsqlparser.parser.ASTNodeAccessImpl; -import java.util.List; - /** * A column. It can have the table name it belongs to. */ @@ -23,6 +22,7 @@ public class Column extends ASTNodeAccessImpl implements Expression, MultiPartNa private Table table; private String columnName; + private String commentText; private ArrayConstructor arrayConstructor; public Column() {} @@ -56,19 +56,19 @@ public Column setArrayConstructor(ArrayConstructor arrayConstructor) { *

* The inference is based only on local information, and not on the whole SQL command. For * example, consider the following query:

- * + * *
      *  SELECT x FROM Foo
      * 
- * + * *
Given the {@code Column} called {@code x}, this method would return * {@code null}, and not the info about the table {@code Foo}. On the other hand, consider: *
- * + * *
      *  SELECT t.x FROM Foo t
      * 
- * + * *
Here, we will get a {@code Table} object for a table called {@code t}. But * because the inference is local, such object will not know that {@code t} is just an alias for * {@code Foo}. @@ -114,6 +114,11 @@ public String getFullyQualifiedName(boolean aliases) { fqn.append(columnName); } + if (commentText != null) { + fqn.append(" COMMENT "); + fqn.append(commentText); + } + if (arrayConstructor != null) { fqn.append(arrayConstructor); } @@ -146,4 +151,17 @@ public Column withColumnName(String columnName) { this.setColumnName(columnName); return this; } + + public Column withCommentText(String commentText) { + this.setCommentText(commentText); + return this; + } + + public void setCommentText(String commentText) { + this.commentText = commentText; + } + + public String getCommentText() { + return commentText; + } } diff --git a/src/main/java/net/sf/jsqlparser/statement/DescribeStatement.java b/src/main/java/net/sf/jsqlparser/statement/DescribeStatement.java index 09d84c2e7..8a2ab01d4 100644 --- a/src/main/java/net/sf/jsqlparser/statement/DescribeStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/DescribeStatement.java @@ -14,6 +14,7 @@ public class DescribeStatement implements Statement { private Table table; + private String describeType; public DescribeStatement() { // empty constructor @@ -33,7 +34,7 @@ public void setTable(Table table) { @Override public String toString() { - return "DESCRIBE " + table.getFullyQualifiedName(); + return this.describeType + " " + table.getFullyQualifiedName(); } @Override @@ -45,4 +46,13 @@ public DescribeStatement withTable(Table table) { this.setTable(table); return this; } + + public String getDescribeType() { + return describeType; + } + + public DescribeStatement setDescribeType(String describeType) { + this.describeType = describeType; + return this; + } } diff --git a/src/main/java/net/sf/jsqlparser/statement/ExplainStatement.java b/src/main/java/net/sf/jsqlparser/statement/ExplainStatement.java index 2957472db..01e7c2f18 100644 --- a/src/main/java/net/sf/jsqlparser/statement/ExplainStatement.java +++ b/src/main/java/net/sf/jsqlparser/statement/ExplainStatement.java @@ -9,11 +9,11 @@ */ package net.sf.jsqlparser.statement; -import net.sf.jsqlparser.statement.select.Select; - import java.io.Serializable; import java.util.LinkedHashMap; import java.util.stream.Collectors; +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.select.Select; /** * An {@code EXPLAIN} statement @@ -22,11 +22,21 @@ public class ExplainStatement implements Statement { private Select select; private LinkedHashMap options; + private Table table; public ExplainStatement() { // empty constructor } + public Table getTable() { + return table; + } + + public ExplainStatement setTable(Table table) { + this.table = table; + return this; + } + public ExplainStatement(Select select) { this.select = select; } @@ -68,14 +78,21 @@ public Option getOption(OptionType optionType) { @Override public String toString() { StringBuilder statementBuilder = new StringBuilder("EXPLAIN"); - if (options != null) { + if (table != null) { + statementBuilder.append(" ").append(table); + } else { + if (options != null) { + statementBuilder.append(" "); + statementBuilder.append(options.values().stream().map(Option::formatOption) + .collect(Collectors.joining(" "))); + } + statementBuilder.append(" "); - statementBuilder.append(options.values().stream().map(Option::formatOption) - .collect(Collectors.joining(" "))); + if (select != null) { + statementBuilder.append(select.toString()); + } } - statementBuilder.append(" "); - statementBuilder.append(select.toString()); return statementBuilder.toString(); } diff --git a/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java b/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java index 86621f749..46d4e0d96 100644 --- a/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java +++ b/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java @@ -29,6 +29,7 @@ import net.sf.jsqlparser.statement.grant.Grant; import net.sf.jsqlparser.statement.insert.Insert; import net.sf.jsqlparser.statement.merge.Merge; +import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.show.ShowIndexStatement; import net.sf.jsqlparser.statement.show.ShowTablesStatement; @@ -68,6 +69,8 @@ public interface StatementVisitor { void visit(AlterView alterView); + void visit(RefreshMaterializedViewStatement materializedView); + void visit(Alter alter); void visit(Statements stmts); diff --git a/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java index 251fcc15b..72d2a540a 100644 --- a/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java +++ b/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java @@ -29,6 +29,7 @@ import net.sf.jsqlparser.statement.grant.Grant; import net.sf.jsqlparser.statement.insert.Insert; import net.sf.jsqlparser.statement.merge.Merge; +import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.show.ShowIndexStatement; import net.sf.jsqlparser.statement.show.ShowTablesStatement; @@ -222,4 +223,9 @@ public void visit(AlterSystemStatement alterSystemStatement) {} public void visit(UnsupportedStatement unsupportedStatement) { } + + @Override + public void visit(RefreshMaterializedViewStatement materializedView) { + + } } diff --git a/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java b/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java index 2902c0833..f31de0da3 100644 --- a/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java +++ b/src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java @@ -12,14 +12,12 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; - import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Optional; import java.util.Set; - import net.sf.jsqlparser.statement.ReferentialAction; import net.sf.jsqlparser.statement.ReferentialAction.Action; import net.sf.jsqlparser.statement.ReferentialAction.Type; @@ -31,743 +29,785 @@ @SuppressWarnings({"PMD.CyclomaticComplexity"}) public class AlterExpression implements Serializable { - private AlterOperation operation; - private String optionalSpecifier; - private String newTableName; - private String columnName; - private String columnOldName; - // private ColDataType dataType; + private AlterOperation operation; + private String optionalSpecifier; + private String newTableName; + private String columnName; + private String columnOldName; + // private ColDataType dataType; - private List colDataTypeList; - private List columnDropNotNullList; + private List colDataTypeList; + private List columnDropNotNullList; - private List columnDropDefaultList; - - private List pkColumns; - private List ukColumns; - private String ukName; - private Index index = null; - private String constraintName; - private boolean usingIfExists; - - private Set referentialActions = new LinkedHashSet<>(2); - - private List fkColumns; - private String fkSourceSchema; - - private String fkSourceTable; - private List fkSourceColumns; - private boolean uk; - private boolean useEqual; - - private List constraints; - private List parameters; - private String commentText; - - private boolean hasColumn = false; - - - private boolean useBrackets=false; - - public boolean hasColumn() { - return hasColumn; - } - - public boolean useBrackets() { - return useBrackets; - } - - public void useBrackets(boolean useBrackets) { - this.useBrackets = useBrackets; - } - - public void hasColumn(boolean hasColumn) { - this.hasColumn = hasColumn; - } - - public String getFkSourceSchema() { - return fkSourceSchema; - } - - public void setFkSourceSchema(String fkSourceSchema) { - this.fkSourceSchema = fkSourceSchema; - } - - public String getCommentText() { - return commentText; - } - - public void setCommentText(String commentText) { - this.commentText = commentText; - } - - public AlterOperation getOperation() { - return operation; - } - - public void setOperation(AlterOperation operation) { - this.operation = operation; - } - - public String getOptionalSpecifier() { - return optionalSpecifier; - } - - public void setOptionalSpecifier(String optionalSpecifier) { - this.optionalSpecifier = optionalSpecifier; - } - - /** - * @param type - * @param action - */ - public void setReferentialAction(Type type, Action action) { - setReferentialAction(type, action, true); - } - - public AlterExpression withReferentialAction(Type type, Action action) { - setReferentialAction(type, action); - return this; - } - - /** @param type */ - public void removeReferentialAction(Type type) { - setReferentialAction(type, null, false); - } - - /** - * @param type - * @return - */ - public ReferentialAction getReferentialAction(Type type) { - return referentialActions.stream() - .filter(ra -> type.equals(ra.getType())) - .findFirst() - .orElse(null); - } - - private void setReferentialAction(Type type, Action action, boolean set) { - ReferentialAction found = getReferentialAction(type); - if (set) { - if (found == null) { - referentialActions.add(new ReferentialAction(type, action)); - } else { - found.setAction(action); - } - } else if (found != null) { - referentialActions.remove(found); - } - } - /** - * @return - * @deprecated use {@link #getReferentialAction(ReferentialAction.Type)} - */ - @Deprecated - public boolean isOnDeleteCascade() { - ReferentialAction found = getReferentialAction(Type.DELETE); - return found != null && Action.CASCADE.equals(found.getAction()); - } - - /** - * @param onDeleteCascade - * @deprecated use {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)} - */ - @Deprecated - public void setOnDeleteCascade(boolean onDeleteCascade) { - setReferentialAction(Type.DELETE, Action.CASCADE, onDeleteCascade); - } - - /** - * @return - * @deprecated use {@link #getReferentialAction(ReferentialAction.Type)} - */ - @Deprecated - public boolean isOnDeleteRestrict() { - ReferentialAction found = getReferentialAction(Type.DELETE); - return found != null && Action.RESTRICT.equals(found.getAction()); - } - - /** - * @param onDeleteRestrict - * @deprecated use {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)} - */ - @Deprecated - public void setOnDeleteRestrict(boolean onDeleteRestrict) { - setReferentialAction(Type.DELETE, Action.RESTRICT, onDeleteRestrict); - } - - /** - * @return - * @deprecated use {@link #getReferentialAction(ReferentialAction.Type)} - */ - @Deprecated - public boolean isOnDeleteSetNull() { - ReferentialAction found = getReferentialAction(Type.DELETE); - return found != null && Action.SET_NULL.equals(found.getAction()); - } - - /** - * @param onDeleteSetNull - * @deprecated use {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)} - */ - @Deprecated - public void setOnDeleteSetNull(boolean onDeleteSetNull) { - setReferentialAction(Type.DELETE, Action.SET_NULL, onDeleteSetNull); - } - - public List getFkColumns() { - return fkColumns; - } - - public void setFkColumns(List fkColumns) { - this.fkColumns = fkColumns; - } - - public String getFkSourceTable() { - return fkSourceTable; - } - - public void setFkSourceTable(String fkSourceTable) { - this.fkSourceTable = fkSourceTable; - } - - public List getColDataTypeList() { - return colDataTypeList; - } - - public void addColDataType(String columnName, ColDataType colDataType) { - addColDataType(new ColumnDataType(columnName, false, colDataType, null)); - } - - public void addColDataType(ColumnDataType columnDataType) { - if (colDataTypeList == null) { - colDataTypeList = new ArrayList<>(); - } - colDataTypeList.add(columnDataType); - } - - public void addColDropNotNull(ColumnDropNotNull columnDropNotNull) { - if (columnDropNotNullList == null) { - columnDropNotNullList = new ArrayList<>(); - } - columnDropNotNullList.add(columnDropNotNull); - } - - public void addColDropDefault(ColumnDropDefault columnDropDefault) { - if (columnDropDefaultList == null) { - columnDropDefaultList = new ArrayList<>(); - } - columnDropDefaultList.add(columnDropDefault); - } - - public List getFkSourceColumns() { - return fkSourceColumns; - } - - public void setFkSourceColumns(List fkSourceColumns) { - this.fkSourceColumns = fkSourceColumns; - } - - public String getNewTableName() { - return newTableName; - } - - public void setNewTableName(String newTableName) { - this.newTableName = newTableName; - } - - public String getColumnName() { - return columnName; - } - - public void setColumnName(String columnName) { - this.columnName = columnName; - } - - @Deprecated - public String getColOldName() { - return getColumnOldName(); - } - - @Deprecated - public void setColOldName(String columnOldName) { - setColumnOldName(columnOldName); - } - - public String getColumnOldName() { - return columnOldName; - } - - public void setColumnOldName(String columnOldName) { - this.columnOldName = columnOldName; - } + private List columnDropDefaultList; - public String getConstraintName() { - return this.constraintName; - } + private List pkColumns; + private List ukColumns; + private String ukName; + private Index index = null; + private Index oldIndex = null; + private String constraintName; + private boolean usingIfExists; - public void setConstraintName(final String constraintName) { - this.constraintName = constraintName; - } + private Set referentialActions = new LinkedHashSet<>(2); - public boolean isUsingIfExists() { - return usingIfExists; - } + private List fkColumns; + private String fkSourceSchema; - public void setUsingIfExists(boolean usingIfExists) { - this.usingIfExists = usingIfExists; - } + private String fkSourceTable; + private List fkSourceColumns; + private boolean uk; + private boolean useEqual; - public List getPkColumns() { - return pkColumns; - } + private List constraints; + private List parameters; + private String commentText; - public void setPkColumns(List pkColumns) { - this.pkColumns = pkColumns; - } - - public List getUkColumns() { - return ukColumns; - } - - public void setUkColumns(List ukColumns) { - this.ukColumns = ukColumns; - } - - public String getUkName() { - return ukName; - } - - public void setUkName(String ukName) { - this.ukName = ukName; - } - - public Index getIndex() { - return index; - } - - public void setIndex(Index index) { - this.index = index; - } - - public List getConstraints() { - return constraints; - } - - public void setConstraints(List constraints) { - this.constraints = constraints; - } - - public List getColumnDropNotNullList() { - return columnDropNotNullList; - } - - public void addParameters(String... params) { - if (parameters == null) { - parameters = new ArrayList<>(); - } - parameters.addAll(Arrays.asList(params)); - } - - public List getParameters() { - return parameters; - } - - public boolean getUseEqual() { - return useEqual; - } - - public void setUseEqual(boolean useEqual) { - this.useEqual = useEqual; - } - - public boolean getUk() { - return uk; - } - - public void setUk(boolean uk) { - this.uk = uk; - } - - @Override - @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity", "PMD.ExcessiveMethodLength"}) - public String toString() { - - StringBuilder b = new StringBuilder(); - - if (operation== AlterOperation.UNSPECIFIC) { - b.append(optionalSpecifier); - } else if (operation== AlterOperation.RENAME_TABLE) { - - b.append("RENAME TO ").append(newTableName); - } else if (operation== AlterOperation.DROP_PRIMARY_KEY) { - - b.append("DROP PRIMARY KEY "); - } else if (operation== AlterOperation.DROP_UNIQUE) { - - b.append("DROP UNIQUE (").append(PlainSelect.getStringList(pkColumns)).append(')'); - } else if (operation== AlterOperation.DROP_FOREIGN_KEY) { - - b.append("DROP FOREIGN KEY (").append(PlainSelect.getStringList(pkColumns)).append(')'); - } else if (operation== AlterOperation.DROP && columnName==null && pkColumns!=null && pkColumns.size()>0) { - // Oracle Multi Column Drop - b.append("DROP (").append(PlainSelect.getStringList(pkColumns)).append(')'); - } else { - b.append(operation).append(" "); - - if (commentText != null) { - if (columnName != null) { - b.append(columnName).append(" COMMENT "); - } - b.append(commentText); - } else if (columnName != null) { - if (hasColumn) { - b.append("COLUMN "); - } - if (usingIfExists) { - b.append("IF EXISTS "); - } - if (operation == AlterOperation.RENAME) { - b.append(columnOldName).append(" TO "); - } - b.append(columnName); - } else if (getColDataTypeList() != null) { - if (operation == AlterOperation.CHANGE) { - if (optionalSpecifier != null) { - b.append(optionalSpecifier).append(" "); - } - b.append(columnOldName).append(" "); - } else if (colDataTypeList.size() > 1) { - b.append("("); - } else { - if (hasColumn) { - b.append("COLUMN "); - } - } - if (useBrackets && colDataTypeList.size() == 1){ - b.append(" ( "); - } - b.append(PlainSelect.getStringList(colDataTypeList)); - if (useBrackets && colDataTypeList.size() == 1 ){ - b.append(" ) "); - } - if (colDataTypeList.size() > 1) { - b.append(")"); - } - } else if (getColumnDropNotNullList() != null) { - b.append("COLUMN "); - b.append(PlainSelect.getStringList(columnDropNotNullList)); - } else if ( columnDropDefaultList != null && !columnDropDefaultList.isEmpty() ) { - b.append("COLUMN "); - b.append(PlainSelect.getStringList(columnDropDefaultList)); - } else if (constraintName != null) { - b.append("CONSTRAINT "); - if (usingIfExists) { - b.append("IF EXISTS "); - } - b.append(constraintName); - } else if (pkColumns != null) { - b.append("PRIMARY KEY (").append(PlainSelect.getStringList(pkColumns)).append(')'); - } else if (ukColumns != null) { - b.append("UNIQUE"); - if (ukName != null) { - if (getUk()) { - b.append(" KEY "); + private boolean hasColumn = false; + + + private boolean useBrackets = false; + + public Index getOldIndex() { + return oldIndex; + } + + public void setOldIndex(Index oldIndex) { + this.oldIndex = oldIndex; + } + + public boolean hasColumn() { + return hasColumn; + } + + public boolean useBrackets() { + return useBrackets; + } + + public void useBrackets(boolean useBrackets) { + this.useBrackets = useBrackets; + } + + public void hasColumn(boolean hasColumn) { + this.hasColumn = hasColumn; + } + + public String getFkSourceSchema() { + return fkSourceSchema; + } + + public void setFkSourceSchema(String fkSourceSchema) { + this.fkSourceSchema = fkSourceSchema; + } + + public String getCommentText() { + return commentText; + } + + public void setCommentText(String commentText) { + this.commentText = commentText; + } + + public AlterOperation getOperation() { + return operation; + } + + public void setOperation(AlterOperation operation) { + this.operation = operation; + } + + public String getOptionalSpecifier() { + return optionalSpecifier; + } + + public void setOptionalSpecifier(String optionalSpecifier) { + this.optionalSpecifier = optionalSpecifier; + } + + /** + * @param type + * @param action + */ + public void setReferentialAction(Type type, Action action) { + setReferentialAction(type, action, true); + } + + public AlterExpression withReferentialAction(Type type, Action action) { + setReferentialAction(type, action); + return this; + } + + /** + * @param type + */ + public void removeReferentialAction(Type type) { + setReferentialAction(type, null, false); + } + + /** + * @param type + * @return + */ + public ReferentialAction getReferentialAction(Type type) { + return referentialActions.stream() + .filter(ra -> type.equals(ra.getType())) + .findFirst() + .orElse(null); + } + + private void setReferentialAction(Type type, Action action, boolean set) { + ReferentialAction found = getReferentialAction(type); + if (set) { + if (found == null) { + referentialActions.add(new ReferentialAction(type, action)); } else { - b.append(" INDEX "); + found.setAction(action); } - b.append(ukName); - } - b.append(" (").append(PlainSelect.getStringList(ukColumns)).append(")"); - } else if (fkColumns != null) { - b.append("FOREIGN KEY (") - .append(PlainSelect.getStringList(fkColumns)) - .append(") REFERENCES ") - .append( - fkSourceSchema != null && fkSourceSchema.trim().length() > 0 - ? fkSourceSchema + "." - : "") - .append(fkSourceTable) - .append(" (") - .append(PlainSelect.getStringList(fkSourceColumns)) - .append(")"); - referentialActions.forEach(b::append); - } else if (index != null) { - b.append(index); + } else if (found != null) { + referentialActions.remove(found); } + } + /** + * @return + * @deprecated use {@link #getReferentialAction(ReferentialAction.Type)} + */ + @Deprecated + public boolean isOnDeleteCascade() { + ReferentialAction found = getReferentialAction(Type.DELETE); + return found != null && Action.CASCADE.equals(found.getAction()); + } + + /** + * @param onDeleteCascade + * @deprecated use + * {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)} + */ + @Deprecated + public void setOnDeleteCascade(boolean onDeleteCascade) { + setReferentialAction(Type.DELETE, Action.CASCADE, onDeleteCascade); + } + + /** + * @return + * @deprecated use {@link #getReferentialAction(ReferentialAction.Type)} + */ + @Deprecated + public boolean isOnDeleteRestrict() { + ReferentialAction found = getReferentialAction(Type.DELETE); + return found != null && Action.RESTRICT.equals(found.getAction()); + } + + /** + * @param onDeleteRestrict + * @deprecated use + * {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)} + */ + @Deprecated + public void setOnDeleteRestrict(boolean onDeleteRestrict) { + setReferentialAction(Type.DELETE, Action.RESTRICT, onDeleteRestrict); + } + + /** + * @return + * @deprecated use {@link #getReferentialAction(ReferentialAction.Type)} + */ + @Deprecated + public boolean isOnDeleteSetNull() { + ReferentialAction found = getReferentialAction(Type.DELETE); + return found != null && Action.SET_NULL.equals(found.getAction()); + } + + /** + * @param onDeleteSetNull + * @deprecated use + * {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)} + */ + @Deprecated + public void setOnDeleteSetNull(boolean onDeleteSetNull) { + setReferentialAction(Type.DELETE, Action.SET_NULL, onDeleteSetNull); + } + + public List getFkColumns() { + return fkColumns; + } + + public void setFkColumns(List fkColumns) { + this.fkColumns = fkColumns; + } - if (getConstraints() != null && !getConstraints().isEmpty()) { - b.append(' ').append(PlainSelect.getStringList(constraints, false, false)); + public String getFkSourceTable() { + return fkSourceTable; + } + + public void setFkSourceTable(String fkSourceTable) { + this.fkSourceTable = fkSourceTable; + } + + public List getColDataTypeList() { + return colDataTypeList; + } + + public void addColDataType(String columnName, ColDataType colDataType) { + addColDataType(new ColumnDataType(columnName, false, colDataType, null)); + } + + public void addColDataType(ColumnDataType columnDataType) { + if (colDataTypeList == null) { + colDataTypeList = new ArrayList<>(); } - if (getUseEqual()) { - b.append('='); + colDataTypeList.add(columnDataType); + } + + public void addColDropNotNull(ColumnDropNotNull columnDropNotNull) { + if (columnDropNotNullList == null) { + columnDropNotNullList = new ArrayList<>(); } + columnDropNotNullList.add(columnDropNotNull); } - if (parameters != null && !parameters.isEmpty()) { - b.append(' ').append(PlainSelect.getStringList(parameters, false, false)); - } - - return b.toString(); - } - - public AlterExpression withOperation(AlterOperation operation) { - this.setOperation(operation); - return this; - } - - public AlterExpression withOptionalSpecifier(String optionalSpecifier) { - this.setOptionalSpecifier(optionalSpecifier); - return this; - } - - public AlterExpression withColumnName(String columnName) { - this.setColumnName(columnName); - return this; - } - - public AlterExpression withPkColumns(List pkColumns) { - this.setPkColumns(pkColumns); - return this; - } - - public AlterExpression withUkColumns(List ukColumns) { - this.setUkColumns(ukColumns); - return this; - } - - public AlterExpression withUkName(String ukName) { - this.setUkName(ukName); - return this; - } - - public AlterExpression withIndex(Index index) { - this.setIndex(index); - return this; - } - - public AlterExpression withConstraintName(String constraintName) { - this.setConstraintName(constraintName); - return this; - } - - public AlterExpression withUsingIfExists(boolean usingIfExists) { - this.setUsingIfExists(usingIfExists); - return this; - } - - public AlterExpression withOnDeleteRestrict(boolean onDeleteRestrict) { - this.setOnDeleteRestrict(onDeleteRestrict); - return this; - } - - public AlterExpression withOnDeleteSetNull(boolean onDeleteSetNull) { - this.setOnDeleteSetNull(onDeleteSetNull); - return this; - } - - public AlterExpression withOnDeleteCascade(boolean onDeleteCascade) { - this.setOnDeleteCascade(onDeleteCascade); - return this; - } - - public AlterExpression withFkColumns(List fkColumns) { - this.setFkColumns(fkColumns); - return this; - } - - public AlterExpression withFkSourceSchema(String fkSourceSchema) { - this.setFkSourceTable(fkSourceSchema); - return this; - } - - public AlterExpression withFkSourceTable(String fkSourceTable) { - this.setFkSourceTable(fkSourceTable); - return this; - } - - public AlterExpression withFkSourceColumns(List fkSourceColumns) { - this.setFkSourceColumns(fkSourceColumns); - return this; - } - - public AlterExpression withUk(boolean uk) { - this.setUk(uk); - return this; - } - - public AlterExpression withUseEqual(boolean useEqual) { - this.setUseEqual(useEqual); - return this; - } - - public AlterExpression withConstraints(List constraints) { - this.setConstraints(constraints); - return this; - } - - public AlterExpression withCommentText(String commentText) { - this.setCommentText(commentText); - return this; - } - - public AlterExpression withColumnOldName(String columnOldName) { - setColumnOldName(columnOldName); - return this; - } - - public AlterExpression addPkColumns(String... pkColumns) { - List collection = Optional.ofNullable(getPkColumns()).orElseGet(ArrayList::new); - Collections.addAll(collection, pkColumns); - return this.withPkColumns(collection); - } - - public AlterExpression addPkColumns(Collection pkColumns) { - List collection = Optional.ofNullable(getPkColumns()).orElseGet(ArrayList::new); - collection.addAll(pkColumns); - return this.withPkColumns(collection); - } - - public AlterExpression addUkColumns(String... ukColumns) { - List collection = Optional.ofNullable(getUkColumns()).orElseGet(ArrayList::new); - Collections.addAll(collection, ukColumns); - return this.withUkColumns(collection); - } - - public AlterExpression addUkColumns(Collection ukColumns) { - List collection = Optional.ofNullable(getUkColumns()).orElseGet(ArrayList::new); - collection.addAll(ukColumns); - return this.withUkColumns(collection); - } - - public AlterExpression addFkColumns(String... fkColumns) { - List collection = Optional.ofNullable(getFkColumns()).orElseGet(ArrayList::new); - Collections.addAll(collection, fkColumns); - return this.withFkColumns(collection); - } - - public AlterExpression addFkColumns(Collection fkColumns) { - List collection = Optional.ofNullable(getFkColumns()).orElseGet(ArrayList::new); - collection.addAll(fkColumns); - return this.withFkColumns(collection); - } - - public AlterExpression addFkSourceColumns(String... fkSourceColumns) { - List collection = Optional.ofNullable(getFkSourceColumns()).orElseGet(ArrayList::new); - Collections.addAll(collection, fkSourceColumns); - return this.withFkSourceColumns(collection); - } - - public AlterExpression addFkSourceColumns(Collection fkSourceColumns) { - List collection = Optional.ofNullable(getFkSourceColumns()).orElseGet(ArrayList::new); - collection.addAll(fkSourceColumns); - return this.withFkSourceColumns(collection); - } - - public AlterExpression addConstraints(ConstraintState... constraints) { - List collection = - Optional.ofNullable(getConstraints()).orElseGet(ArrayList::new); - Collections.addAll(collection, constraints); - return this.withConstraints(collection); - } - - public AlterExpression addConstraints(Collection constraints) { - List collection = - Optional.ofNullable(getConstraints()).orElseGet(ArrayList::new); - collection.addAll(constraints); - return this.withConstraints(collection); - } - - public static final class ColumnDataType extends ColumnDefinition { - - private final boolean withType; - - public ColumnDataType(boolean withType) { - super(); - this.withType = withType; - } - - public ColumnDataType( - String columnName, boolean withType, ColDataType colDataType, List columnSpecs) { - super(columnName, colDataType, columnSpecs); - this.withType = withType; + public void addColDropDefault(ColumnDropDefault columnDropDefault) { + if (columnDropDefaultList == null) { + columnDropDefaultList = new ArrayList<>(); + } + columnDropDefaultList.add(columnDropDefault); } - @Override - public String toString() { - return getColumnName() + (withType ? " TYPE " : " ") + toStringDataTypeAndSpec(); + public List getFkSourceColumns() { + return fkSourceColumns; } - @Override - public ColumnDataType withColDataType(ColDataType colDataType) { - return (ColumnDataType) super.withColDataType(colDataType); + public void setFkSourceColumns(List fkSourceColumns) { + this.fkSourceColumns = fkSourceColumns; } - @Override - public ColumnDataType withColumnName(String columnName) { - return (ColumnDataType) super.withColumnName(columnName); + public String getNewTableName() { + return newTableName; } - @Override - public ColumnDataType addColumnSpecs(String... columnSpecs) { - return (ColumnDataType) super.addColumnSpecs(columnSpecs); + public void setNewTableName(String newTableName) { + this.newTableName = newTableName; } - @Override - public ColumnDataType addColumnSpecs(Collection columnSpecs) { - return (ColumnDataType) super.addColumnSpecs(columnSpecs); + public String getColumnName() { + return columnName; } - @Override - public ColumnDataType withColumnSpecs(List columnSpecs) { - return (ColumnDataType) super.withColumnSpecs(columnSpecs); + public void setColumnName(String columnName) { + this.columnName = columnName; } - } - public static final class ColumnDropNotNull implements Serializable { + @Deprecated + public String getColOldName() { + return getColumnOldName(); + } - private final String columnName; - private final boolean withNot; + @Deprecated + public void setColOldName(String columnOldName) { + setColumnOldName(columnOldName); + } - public ColumnDropNotNull(String columnName) { - this(columnName, false); + public String getColumnOldName() { + return columnOldName; } - public ColumnDropNotNull(String columnName, boolean withNot) { - this.columnName = columnName; - this.withNot = withNot; + public void setColumnOldName(String columnOldName) { + this.columnOldName = columnOldName; } - public String getColumnName() { - return columnName; + public String getConstraintName() { + return this.constraintName; } - public boolean isWithNot() { - return withNot; + public void setConstraintName(final String constraintName) { + this.constraintName = constraintName; } - @Override - public String toString() { - return columnName + " DROP" + (withNot ? " NOT " : " ") + "NULL"; + public boolean isUsingIfExists() { + return usingIfExists; } - } - public static final class ColumnDropDefault implements Serializable { + public void setUsingIfExists(boolean usingIfExists) { + this.usingIfExists = usingIfExists; + } - private final String columnName; + public List getPkColumns() { + return pkColumns; + } - public ColumnDropDefault(String columnName) { - this.columnName = columnName; + public void setPkColumns(List pkColumns) { + this.pkColumns = pkColumns; } - public String getColumnName() { - return columnName; + public List getUkColumns() { + return ukColumns; + } + + public void setUkColumns(List ukColumns) { + this.ukColumns = ukColumns; + } + + public String getUkName() { + return ukName; + } + + public void setUkName(String ukName) { + this.ukName = ukName; + } + + public Index getIndex() { + return index; + } + + public void setIndex(Index index) { + this.index = index; + } + + public List getConstraints() { + return constraints; + } + + public void setConstraints(List constraints) { + this.constraints = constraints; + } + + public List getColumnDropNotNullList() { + return columnDropNotNullList; + } + + public void addParameters(String... params) { + if (parameters == null) { + parameters = new ArrayList<>(); + } + parameters.addAll(Arrays.asList(params)); + } + + public List getParameters() { + return parameters; + } + + public boolean getUseEqual() { + return useEqual; + } + + public void setUseEqual(boolean useEqual) { + this.useEqual = useEqual; + } + + public boolean getUk() { + return uk; + } + + public void setUk(boolean uk) { + this.uk = uk; } @Override + @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity", + "PMD.ExcessiveMethodLength", "PMD.SwitchStmtsShouldHaveDefault"}) public String toString() { - return columnName + " DROP DEFAULT"; + + StringBuilder b = new StringBuilder(); + + if (operation == AlterOperation.UNSPECIFIC) { + b.append(optionalSpecifier); + } else if (getOldIndex() != null) { + b.append("RENAME"); + switch (operation) { + case RENAME_KEY: + b.append(" KEY "); + break; + case RENAME_INDEX: + b.append(" INDEX "); + break; + case RENAME_CONSTRAINT: + b.append(" CONSTRAINT "); + break; + } + b.append(getOldIndex().getName()).append(" TO ").append(getIndex().getName()); + } else if (operation == AlterOperation.RENAME_TABLE) { + + b.append("RENAME TO ").append(newTableName); + } else if (operation == AlterOperation.DROP_PRIMARY_KEY) { + + b.append("DROP PRIMARY KEY "); + } else if (operation == AlterOperation.DROP_UNIQUE) { + + b.append("DROP UNIQUE (").append(PlainSelect.getStringList(pkColumns)).append(')'); + } else if (operation == AlterOperation.DROP_FOREIGN_KEY) { + + b.append("DROP FOREIGN KEY (").append(PlainSelect.getStringList(pkColumns)).append(')'); + } else if (operation == AlterOperation.DROP && columnName == null && pkColumns != null + && !pkColumns.isEmpty()) { + // Oracle Multi Column Drop + b.append("DROP (").append(PlainSelect.getStringList(pkColumns)).append(')'); + } else { + if (operation == AlterOperation.COMMENT_WITH_EQUAL_SIGN) { + b.append("COMMENT =").append(" "); + } else { + b.append(operation).append(" "); + } + if (commentText != null) { + if (columnName != null) { + b.append(columnName).append(" COMMENT "); + } + b.append(commentText); + } else if (columnName != null) { + if (hasColumn) { + b.append("COLUMN "); + } + if (usingIfExists) { + b.append("IF EXISTS "); + } + if (operation == AlterOperation.RENAME) { + b.append(columnOldName).append(" TO "); + } + b.append(columnName); + } else if (getColDataTypeList() != null) { + if (operation == AlterOperation.CHANGE) { + if (optionalSpecifier != null) { + b.append(optionalSpecifier).append(" "); + } + b.append(columnOldName).append(" "); + } else if (colDataTypeList.size() > 1) { + b.append("("); + } else { + if (hasColumn) { + b.append("COLUMN "); + } + } + if (useBrackets && colDataTypeList.size() == 1) { + b.append(" ( "); + } + b.append(PlainSelect.getStringList(colDataTypeList)); + if (useBrackets && colDataTypeList.size() == 1) { + b.append(" ) "); + } + if (colDataTypeList.size() > 1) { + b.append(")"); + } + } else if (getColumnDropNotNullList() != null) { + b.append("COLUMN "); + b.append(PlainSelect.getStringList(columnDropNotNullList)); + } else if (columnDropDefaultList != null && !columnDropDefaultList.isEmpty()) { + b.append("COLUMN "); + b.append(PlainSelect.getStringList(columnDropDefaultList)); + } else if (constraintName != null) { + b.append("CONSTRAINT "); + if (usingIfExists) { + b.append("IF EXISTS "); + } + b.append(constraintName); + } else if (pkColumns != null) { + b.append("PRIMARY KEY (").append(PlainSelect.getStringList(pkColumns)).append(')'); + } else if (ukColumns != null) { + b.append("UNIQUE"); + if (ukName != null) { + if (getUk()) { + b.append(" KEY "); + } else { + b.append(" INDEX "); + } + b.append(ukName); + } + b.append(" (").append(PlainSelect.getStringList(ukColumns)).append(")"); + } else if (fkColumns != null) { + b.append("FOREIGN KEY (") + .append(PlainSelect.getStringList(fkColumns)) + .append(") REFERENCES ") + .append( + fkSourceSchema != null && fkSourceSchema.trim().length() > 0 + ? fkSourceSchema + "." + : "") + .append(fkSourceTable) + .append(" (") + .append(PlainSelect.getStringList(fkSourceColumns)) + .append(")"); + referentialActions.forEach(b::append); + } else if (index != null) { + b.append(index); + } + + + if (getConstraints() != null && !getConstraints().isEmpty()) { + b.append(' ').append(PlainSelect.getStringList(constraints, false, false)); + } + if (getUseEqual()) { + b.append('='); + } + } + + if (parameters != null && !parameters.isEmpty()) { + b.append(' ').append(PlainSelect.getStringList(parameters, false, false)); + } + + if (index != null && index.getCommentText() != null) { + // `USING` is a parameters + b.append(" COMMENT ").append(index.getCommentText()); + } + + return b.toString(); + } + + public AlterExpression withOperation(AlterOperation operation) { + this.setOperation(operation); + return this; + } + + public AlterExpression withOptionalSpecifier(String optionalSpecifier) { + this.setOptionalSpecifier(optionalSpecifier); + return this; + } + + public AlterExpression withColumnName(String columnName) { + this.setColumnName(columnName); + return this; + } + + public AlterExpression withPkColumns(List pkColumns) { + this.setPkColumns(pkColumns); + return this; + } + + public AlterExpression withUkColumns(List ukColumns) { + this.setUkColumns(ukColumns); + return this; + } + + public AlterExpression withUkName(String ukName) { + this.setUkName(ukName); + return this; + } + + public AlterExpression withIndex(Index index) { + this.setIndex(index); + return this; + } + + public AlterExpression withConstraintName(String constraintName) { + this.setConstraintName(constraintName); + return this; + } + + public AlterExpression withUsingIfExists(boolean usingIfExists) { + this.setUsingIfExists(usingIfExists); + return this; + } + + public AlterExpression withOnDeleteRestrict(boolean onDeleteRestrict) { + this.setOnDeleteRestrict(onDeleteRestrict); + return this; + } + + public AlterExpression withOnDeleteSetNull(boolean onDeleteSetNull) { + this.setOnDeleteSetNull(onDeleteSetNull); + return this; + } + + public AlterExpression withOnDeleteCascade(boolean onDeleteCascade) { + this.setOnDeleteCascade(onDeleteCascade); + return this; + } + + public AlterExpression withFkColumns(List fkColumns) { + this.setFkColumns(fkColumns); + return this; + } + + public AlterExpression withFkSourceSchema(String fkSourceSchema) { + this.setFkSourceTable(fkSourceSchema); + return this; + } + + public AlterExpression withFkSourceTable(String fkSourceTable) { + this.setFkSourceTable(fkSourceTable); + return this; + } + + public AlterExpression withFkSourceColumns(List fkSourceColumns) { + this.setFkSourceColumns(fkSourceColumns); + return this; + } + + public AlterExpression withUk(boolean uk) { + this.setUk(uk); + return this; + } + + public AlterExpression withUseEqual(boolean useEqual) { + this.setUseEqual(useEqual); + return this; + } + + public AlterExpression withConstraints(List constraints) { + this.setConstraints(constraints); + return this; + } + + public AlterExpression withCommentText(String commentText) { + this.setCommentText(commentText); + return this; + } + + public AlterExpression withColumnOldName(String columnOldName) { + setColumnOldName(columnOldName); + return this; + } + + public AlterExpression addPkColumns(String... pkColumns) { + List collection = Optional.ofNullable(getPkColumns()).orElseGet(ArrayList::new); + Collections.addAll(collection, pkColumns); + return this.withPkColumns(collection); + } + + public AlterExpression addPkColumns(Collection pkColumns) { + List collection = Optional.ofNullable(getPkColumns()).orElseGet(ArrayList::new); + collection.addAll(pkColumns); + return this.withPkColumns(collection); + } + + public AlterExpression addUkColumns(String... ukColumns) { + List collection = Optional.ofNullable(getUkColumns()).orElseGet(ArrayList::new); + Collections.addAll(collection, ukColumns); + return this.withUkColumns(collection); + } + + public AlterExpression addUkColumns(Collection ukColumns) { + List collection = Optional.ofNullable(getUkColumns()).orElseGet(ArrayList::new); + collection.addAll(ukColumns); + return this.withUkColumns(collection); + } + + public AlterExpression addFkColumns(String... fkColumns) { + List collection = Optional.ofNullable(getFkColumns()).orElseGet(ArrayList::new); + Collections.addAll(collection, fkColumns); + return this.withFkColumns(collection); + } + + public AlterExpression addFkColumns(Collection fkColumns) { + List collection = Optional.ofNullable(getFkColumns()).orElseGet(ArrayList::new); + collection.addAll(fkColumns); + return this.withFkColumns(collection); + } + + public AlterExpression addFkSourceColumns(String... fkSourceColumns) { + List collection = + Optional.ofNullable(getFkSourceColumns()).orElseGet(ArrayList::new); + Collections.addAll(collection, fkSourceColumns); + return this.withFkSourceColumns(collection); + } + + public AlterExpression addFkSourceColumns(Collection fkSourceColumns) { + List collection = + Optional.ofNullable(getFkSourceColumns()).orElseGet(ArrayList::new); + collection.addAll(fkSourceColumns); + return this.withFkSourceColumns(collection); + } + + public AlterExpression addConstraints(ConstraintState... constraints) { + List collection = + Optional.ofNullable(getConstraints()).orElseGet(ArrayList::new); + Collections.addAll(collection, constraints); + return this.withConstraints(collection); + } + + public AlterExpression addConstraints(Collection constraints) { + List collection = + Optional.ofNullable(getConstraints()).orElseGet(ArrayList::new); + collection.addAll(constraints); + return this.withConstraints(collection); + } + + public static final class ColumnDataType extends ColumnDefinition { + + private final boolean withType; + + public ColumnDataType(boolean withType) { + super(); + this.withType = withType; + } + + public ColumnDataType( + String columnName, boolean withType, ColDataType colDataType, + List columnSpecs) { + super(columnName, colDataType, columnSpecs); + this.withType = withType; + } + + @Override + public String toString() { + return getColumnName() + (withType ? " TYPE " : " ") + toStringDataTypeAndSpec(); + } + + @Override + public ColumnDataType withColDataType(ColDataType colDataType) { + return (ColumnDataType) super.withColDataType(colDataType); + } + + @Override + public ColumnDataType withColumnName(String columnName) { + return (ColumnDataType) super.withColumnName(columnName); + } + + @Override + public ColumnDataType addColumnSpecs(String... columnSpecs) { + return (ColumnDataType) super.addColumnSpecs(columnSpecs); + } + + @Override + public ColumnDataType addColumnSpecs(Collection columnSpecs) { + return (ColumnDataType) super.addColumnSpecs(columnSpecs); + } + + @Override + public ColumnDataType withColumnSpecs(List columnSpecs) { + return (ColumnDataType) super.withColumnSpecs(columnSpecs); + } + } + + public static final class ColumnDropNotNull implements Serializable { + + private final String columnName; + private final boolean withNot; + + public ColumnDropNotNull(String columnName) { + this(columnName, false); + } + + public ColumnDropNotNull(String columnName, boolean withNot) { + this.columnName = columnName; + this.withNot = withNot; + } + + public String getColumnName() { + return columnName; + } + + public boolean isWithNot() { + return withNot; + } + + @Override + public String toString() { + return columnName + " DROP" + (withNot ? " NOT " : " ") + "NULL"; + } + } + + public static final class ColumnDropDefault implements Serializable { + + private final String columnName; + + public ColumnDropDefault(String columnName) { + this.columnName = columnName; + } + + public String getColumnName() { + return columnName; + } + + @Override + public String toString() { + return columnName + " DROP DEFAULT"; + } } - } } diff --git a/src/main/java/net/sf/jsqlparser/statement/alter/AlterOperation.java b/src/main/java/net/sf/jsqlparser/statement/alter/AlterOperation.java index bb13956f4..adddaa14d 100644 --- a/src/main/java/net/sf/jsqlparser/statement/alter/AlterOperation.java +++ b/src/main/java/net/sf/jsqlparser/statement/alter/AlterOperation.java @@ -10,7 +10,7 @@ package net.sf.jsqlparser.statement.alter; public enum AlterOperation { - ADD, ALTER, DROP, DROP_PRIMARY_KEY, DROP_UNIQUE, DROP_FOREIGN_KEY, MODIFY, CHANGE, ALGORITHM, RENAME, RENAME_TABLE, COMMENT, UNSPECIFIC; + ADD, ALTER, DROP, DROP_PRIMARY_KEY, DROP_UNIQUE, DROP_FOREIGN_KEY, MODIFY, CHANGE, ALGORITHM, RENAME, RENAME_TABLE, RENAME_INDEX, RENAME_KEY, RENAME_CONSTRAINT, COMMENT, COMMENT_WITH_EQUAL_SIGN, UNSPECIFIC; public static AlterOperation from(String operation) { return Enum.valueOf(AlterOperation.class, operation.toUpperCase()); diff --git a/src/main/java/net/sf/jsqlparser/statement/create/index/CreateIndex.java b/src/main/java/net/sf/jsqlparser/statement/create/index/CreateIndex.java index 806eda9a6..3fc4fcbf1 100644 --- a/src/main/java/net/sf/jsqlparser/statement/create/index/CreateIndex.java +++ b/src/main/java/net/sf/jsqlparser/statement/create/index/CreateIndex.java @@ -9,18 +9,38 @@ */ package net.sf.jsqlparser.statement.create.index; +import static java.util.stream.Collectors.joining; + +import java.util.*; import net.sf.jsqlparser.schema.*; import net.sf.jsqlparser.statement.*; import net.sf.jsqlparser.statement.create.table.*; -import java.util.*; -import static java.util.stream.Collectors.joining; - public class CreateIndex implements Statement { private Table table; private Index index; private List tailParameters; + private boolean indexTypeBeforeOn = false; + + public boolean isIndexTypeBeforeOn() { + return indexTypeBeforeOn; + } + + public void setIndexTypeBeforeOn(boolean indexTypeBeforeOn) { + this.indexTypeBeforeOn = indexTypeBeforeOn; + } + + public boolean isUsingIfNotExists() { + return usingIfNotExists; + } + + public CreateIndex setUsingIfNotExists(boolean usingIfNotExists) { + this.usingIfNotExists = usingIfNotExists; + return this; + } + + private boolean usingIfNotExists = false; @Override public void accept(StatementVisitor statementVisitor) { @@ -63,11 +83,20 @@ public String toString() { } buffer.append("INDEX "); + if (usingIfNotExists) { + buffer.append("IF NOT EXISTS "); + } buffer.append(index.getName()); + + if (index.getUsing() != null && isIndexTypeBeforeOn()) { + buffer.append(" USING "); + buffer.append(index.getUsing()); + } + buffer.append(" ON "); buffer.append(table.getFullyQualifiedName()); - if (index.getUsing() != null) { + if (index.getUsing() != null && !isIndexTypeBeforeOn()) { buffer.append(" USING "); buffer.append(index.getUsing()); } @@ -77,8 +106,10 @@ public String toString() { buffer.append( index.getColumns().stream() - .map(cp -> cp.columnName + (cp.getParams() != null ? " " + String.join(" ", cp.getParams()) : "")).collect(joining(", ")) - ); + .map(cp -> cp.columnName + (cp.getParams() != null + ? " " + String.join(" ", cp.getParams()) + : "")) + .collect(joining(", "))); buffer.append(")"); diff --git a/src/main/java/net/sf/jsqlparser/statement/create/table/Index.java b/src/main/java/net/sf/jsqlparser/statement/create/table/Index.java index 091dfb7af..720fa1abe 100644 --- a/src/main/java/net/sf/jsqlparser/statement/create/table/Index.java +++ b/src/main/java/net/sf/jsqlparser/statement/create/table/Index.java @@ -26,6 +26,7 @@ public class Index implements Serializable { private List columns; private final List name = new ArrayList<>(); private List idxSpec; + private String commentText; public List getColumnsNames() { return columns.stream() @@ -81,12 +82,11 @@ public String getType() { } /** - * In postgresql, the index type (Btree, GIST, etc.) is indicated - * with a USING clause. - * Please note that: - * Oracle - the type might be BITMAP, indicating a bitmap kind of index - * MySQL - the type might be FULLTEXT or SPATIAL - * @param using + * In postgresql, the index type (Btree, GIST, etc.) is indicated with a USING clause. Please + * note that: Oracle - the type might be BITMAP, indicating a bitmap kind of index MySQL - the + * type might be FULLTEXT or SPATIAL + * + * @param using */ public void setUsing(String using) { this.using = using; @@ -135,8 +135,15 @@ public Index withIndexSpec(List idxSpec) { @Override public String toString() { String idxSpecText = PlainSelect.getStringList(idxSpec, false, false); - return ( type!=null ? type : "") + (!name.isEmpty() ? " " + getName() : "") + " " + PlainSelect. - getStringList(columns, true, true) + (!"".equals(idxSpecText) ? " " + idxSpecText : ""); + String head = (type != null ? type : "") + (!name.isEmpty() ? " " + getName() : ""); + String tail = PlainSelect.getStringList(columns, true, true) + + (!"".equals(idxSpecText) ? " " + idxSpecText : ""); + + if ("".equals(tail)) { + return head; + } + + return head + " " + tail; } public Index withType(String type) { @@ -186,4 +193,12 @@ public String toString() { return columnName + (params != null ? " " + String.join(" ", params) : ""); } } + + public String getCommentText() { + return commentText; + } + + public void setCommentText(String commentText) { + this.commentText = commentText; + } } diff --git a/src/main/java/net/sf/jsqlparser/statement/create/table/NamedConstraint.java b/src/main/java/net/sf/jsqlparser/statement/create/table/NamedConstraint.java index 8f188ebc8..f9a7f391d 100644 --- a/src/main/java/net/sf/jsqlparser/statement/create/table/NamedConstraint.java +++ b/src/main/java/net/sf/jsqlparser/statement/create/table/NamedConstraint.java @@ -18,9 +18,10 @@ public class NamedConstraint extends Index { @Override public String toString() { String idxSpecText = PlainSelect.getStringList(getIndexSpec(), false, false); - return (getName() != null ? "CONSTRAINT " + getName() + " " : "") - + getType() + " " + PlainSelect.getStringList(getColumnsNames(), true, true) + (!"". - equals(idxSpecText) ? " " + idxSpecText : ""); + String head = getName() != null ? "CONSTRAINT " + getName() + " " : ""; + String tail = getType() + " " + PlainSelect.getStringList(getColumnsNames(), true, true) + + (!"".equals(idxSpecText) ? " " + idxSpecText : ""); + return head + tail; } @Override diff --git a/src/main/java/net/sf/jsqlparser/statement/create/view/CreateView.java b/src/main/java/net/sf/jsqlparser/statement/create/view/CreateView.java index a623beb41..8381e50af 100644 --- a/src/main/java/net/sf/jsqlparser/statement/create/view/CreateView.java +++ b/src/main/java/net/sf/jsqlparser/statement/create/view/CreateView.java @@ -9,11 +9,9 @@ */ package net.sf.jsqlparser.statement.create.view; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.List; -import java.util.Optional; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.StatementVisitor; @@ -25,13 +23,14 @@ public class CreateView implements Statement { private Table view; private Select select; private boolean orReplace = false; - private List columnNames = null; + private ExpressionList columnNames = null; private boolean materialized = false; private ForceOption force = ForceOption.NONE; private TemporaryOption temp = TemporaryOption.NONE; private AutoRefreshOption autoRefresh = AutoRefreshOption.NONE; private boolean withReadOnly = false; private boolean ifNotExists = false; + private List viewCommentOptions = null; @Override public void accept(StatementVisitor statementVisitor) { @@ -65,11 +64,11 @@ public void setSelect(Select select) { this.select = select; } - public List getColumnNames() { + public ExpressionList getColumnNames() { return columnNames; } - public void setColumnNames(List columnNames) { + public void setColumnNames(ExpressionList columnNames) { this.columnNames = columnNames; } @@ -145,7 +144,12 @@ public String toString() { sql.append(" AUTO REFRESH ").append(autoRefresh.name()); } if (columnNames != null) { - sql.append(PlainSelect.getStringList(columnNames, true, true)); + sql.append("("); + sql.append(columnNames); + sql.append(")"); + } + if (viewCommentOptions != null) { + sql.append(PlainSelect.getStringList(viewCommentOptions, false, false)); } sql.append(" AS ").append(select); if (isWithReadOnly()) { @@ -182,7 +186,7 @@ public CreateView withOrReplace(boolean orReplace) { return this; } - public CreateView withColumnNames(List columnNames) { + public CreateView withColumnNames(ExpressionList columnNames) { this.setColumnNames(columnNames); return this; } @@ -202,15 +206,11 @@ public CreateView withWithReadOnly(boolean withReadOnly) { return this; } - public CreateView addColumnNames(String... columnNames) { - List collection = Optional.ofNullable(getColumnNames()).orElseGet(ArrayList::new); - Collections.addAll(collection, columnNames); - return this.withColumnNames(collection); + public List getViewCommentOptions() { + return viewCommentOptions; } - public CreateView addColumnNames(Collection columnNames) { - List collection = Optional.ofNullable(getColumnNames()).orElseGet(ArrayList::new); - collection.addAll(columnNames); - return this.withColumnNames(collection); + public void setViewCommentOptions(List viewCommentOptions) { + this.viewCommentOptions = viewCommentOptions; } } diff --git a/src/main/java/net/sf/jsqlparser/statement/delete/Delete.java b/src/main/java/net/sf/jsqlparser/statement/delete/Delete.java index c28a4a0d8..3e5c171a3 100644 --- a/src/main/java/net/sf/jsqlparser/statement/delete/Delete.java +++ b/src/main/java/net/sf/jsqlparser/statement/delete/Delete.java @@ -188,7 +188,9 @@ public String toString() { } b.append("DELETE"); - + if (oracleHint != null) { + b.append(oracleHint).append(" "); + } if (modifierPriority != null) { b.append(" ").append(modifierPriority.name()); } diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java index ea3809ad6..bb5595a35 100644 --- a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java +++ b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java @@ -218,6 +218,9 @@ public String toString() { } } sql.append("INSERT "); + if (oracleHint != null) { + sql.append(oracleHint).append(" "); + } if (modifierPriority != null) { sql.append(modifierPriority.name()).append(" "); } diff --git a/src/main/java/net/sf/jsqlparser/statement/merge/Merge.java b/src/main/java/net/sf/jsqlparser/statement/merge/Merge.java index 32dc3d3bd..0be4d2528 100644 --- a/src/main/java/net/sf/jsqlparser/statement/merge/Merge.java +++ b/src/main/java/net/sf/jsqlparser/statement/merge/Merge.java @@ -13,6 +13,7 @@ import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.OracleHint; import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.OutputClause; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.StatementVisitor; import net.sf.jsqlparser.statement.select.FromItem; @@ -37,6 +38,8 @@ public class Merge implements Statement { private MergeUpdate mergeUpdate; private boolean insertFirst = false; + private OutputClause outputClause; + public List getWithItemsList() { return withItemsList; } @@ -155,6 +158,15 @@ public void setInsertFirst(boolean insertFirst) { this.insertFirst = insertFirst; } + public OutputClause getOutputClause() { + return outputClause; + } + + public Merge setOutputClause(OutputClause outputClause) { + this.outputClause = outputClause; + return this; + } + @Override @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"}) public String toString() { @@ -170,13 +182,16 @@ public String toString() { b.append(" "); } } - b.append("MERGE INTO "); + b.append("MERGE "); + if (oracleHint != null) { + b.append(oracleHint).append(" "); + } + b.append("INTO "); b.append(table); b.append(" USING "); b.append(fromItem); - b.append(" ON ("); + b.append(" ON "); b.append(onCondition); - b.append(")"); if (insertFirst && mergeInsert != null) { b.append(mergeInsert); @@ -190,6 +205,10 @@ public String toString() { b.append(mergeInsert); } + if (outputClause != null) { + b.append(outputClause); + } + return b.toString(); } diff --git a/src/main/java/net/sf/jsqlparser/statement/merge/MergeInsert.java b/src/main/java/net/sf/jsqlparser/statement/merge/MergeInsert.java index bc9ea695a..f6affa3ef 100644 --- a/src/main/java/net/sf/jsqlparser/statement/merge/MergeInsert.java +++ b/src/main/java/net/sf/jsqlparser/statement/merge/MergeInsert.java @@ -20,10 +20,19 @@ public class MergeInsert implements Serializable { + private Expression andPredicate; private ExpressionList columns; private ExpressionList values; private Expression whereCondition; + public Expression getAndPredicate() { + return andPredicate; + } + + public void setAndPredicate(Expression andPredicate) { + this.andPredicate = andPredicate; + } + public ExpressionList getColumns() { return columns; } @@ -50,12 +59,25 @@ public void setWhereCondition(Expression whereCondition) { @Override public String toString() { - return " WHEN NOT MATCHED THEN INSERT " - + (columns != null ? columns.toString() : "") - + " VALUES " + values.toString() - + (whereCondition != null - ? " WHERE " + whereCondition - : ""); + StringBuilder b = new StringBuilder(); + b.append(" WHEN NOT MATCHED"); + if (andPredicate != null) { + b.append(" AND ").append(andPredicate.toString()); + } + b.append(" THEN INSERT "); + if (columns != null) { + b.append(columns.toString()); + } + b.append(" VALUES ").append(values.toString()); + if (whereCondition != null) { + b.append(" WHERE ").append(whereCondition.toString()); + } + return b.toString(); + } + + public MergeInsert withAndPredicate(Expression andPredicate) { + this.setAndPredicate(andPredicate); + return this; } public MergeInsert withColumns(ExpressionList columns) { @@ -95,6 +117,10 @@ public MergeInsert withWhereCondition(Expression whereCondition) { return this; } + public E getAndPredicate(Class type) { + return type.cast(getAndPredicate()); + } + public E getWhereCondition(Class type) { return type.cast(getWhereCondition()); } diff --git a/src/main/java/net/sf/jsqlparser/statement/merge/MergeUpdate.java b/src/main/java/net/sf/jsqlparser/statement/merge/MergeUpdate.java index e69c595f9..38e9261a2 100644 --- a/src/main/java/net/sf/jsqlparser/statement/merge/MergeUpdate.java +++ b/src/main/java/net/sf/jsqlparser/statement/merge/MergeUpdate.java @@ -18,9 +18,12 @@ public class MergeUpdate implements Serializable { private List updateSets; + private Expression andPredicate; private Expression whereCondition; private Expression deleteWhereCondition; + public MergeUpdate() {} + public MergeUpdate(List updateSets) { this.updateSets = updateSets; } @@ -34,6 +37,14 @@ public MergeUpdate setUpdateSets(List updateSets) { return this; } + public Expression getAndPredicate() { + return andPredicate; + } + + public void setAndPredicate(Expression andPredicate) { + this.andPredicate = andPredicate; + } + public Expression getWhereCondition() { return whereCondition; } @@ -53,7 +64,11 @@ public void setDeleteWhereCondition(Expression deleteWhereCondition) { @Override public String toString() { StringBuilder b = new StringBuilder(); - b.append(" WHEN MATCHED THEN UPDATE SET "); + b.append(" WHEN MATCHED"); + if (andPredicate != null) { + b.append(" AND ").append(andPredicate.toString()); + } + b.append(" THEN UPDATE SET "); UpdateSet.appendUpdateSetsTo(b, updateSets); if (whereCondition != null) { @@ -65,6 +80,11 @@ public String toString() { return b.toString(); } + public MergeUpdate withAndPredicate(Expression andPredicate) { + this.setAndPredicate(andPredicate); + return this; + } + public MergeUpdate withWhereCondition(Expression whereCondition) { this.setWhereCondition(whereCondition); return this; @@ -75,6 +95,10 @@ public MergeUpdate withDeleteWhereCondition(Expression deleteWhereCondition) { return this; } + public E getAndPredicate(Class type) { + return type.cast(getAndPredicate()); + } + public E getWhereCondition(Class type) { return type.cast(getWhereCondition()); } diff --git a/src/main/java/net/sf/jsqlparser/statement/refresh/RefreshMaterializedViewStatement.java b/src/main/java/net/sf/jsqlparser/statement/refresh/RefreshMaterializedViewStatement.java new file mode 100644 index 000000000..86b530ed3 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/statement/refresh/RefreshMaterializedViewStatement.java @@ -0,0 +1,107 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2019 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement.refresh; + +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.Statement; +import net.sf.jsqlparser.statement.StatementVisitor; + +/** + * REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] name [ WITH [ NO ] DATA ] + *

+ * https://www.postgresql.org/docs/16/sql-refreshmaterializedview.html + * + * @author jxnu-liguobin + */ + +public class RefreshMaterializedViewStatement implements Statement { + + private Table view; + private RefreshMode refreshMode; + private boolean concurrently = false; + + public RefreshMaterializedViewStatement() {} + + public RefreshMaterializedViewStatement(Table view, boolean concurrently, + RefreshMode refreshMode) { + this.refreshMode = refreshMode; + this.concurrently = concurrently; + this.view = view; + } + + public Table getView() { + return view; + } + + public void setView(Table view) { + this.view = view; + } + + public RefreshMode getRefreshMode() { + return refreshMode; + } + + public void setRefreshMode(RefreshMode refreshMode) { + this.refreshMode = refreshMode; + } + + public boolean isConcurrently() { + return concurrently; + } + + public void setConcurrently(boolean concurrently) { + this.concurrently = concurrently; + } + + @SuppressWarnings("PMD.SwitchStmtsShouldHaveDefault") + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("REFRESH MATERIALIZED VIEW "); + if (this.refreshMode == null) { + if (concurrently) { + builder.append("CONCURRENTLY "); + } + builder.append(view); + return builder.toString(); + } + switch (this.refreshMode) { + case WITH_DATA: + if (concurrently) { + builder.append("CONCURRENTLY "); + } + builder.append(view); + builder.append(" WITH DATA"); + break; + case WITH_NO_DATA: + builder.append(view); + if (!concurrently) { + builder.append(" WITH NO DATA"); + } + break; + } + return builder.toString(); + } + + @Override + public void accept(StatementVisitor statementVisitor) { + statementVisitor.visit(this); + } + + public RefreshMaterializedViewStatement withTableName(Table view) { + this.setView(view); + return this; + } + + public RefreshMaterializedViewStatement withConcurrently(boolean concurrently) { + this.setConcurrently(concurrently); + return this; + } +} diff --git a/src/main/java/net/sf/jsqlparser/statement/refresh/RefreshMode.java b/src/main/java/net/sf/jsqlparser/statement/refresh/RefreshMode.java new file mode 100644 index 000000000..fb78fac5d --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/statement/refresh/RefreshMode.java @@ -0,0 +1,19 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2022 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement.refresh; + +public enum RefreshMode { + + DEFAULT, WITH_DATA, WITH_NO_DATA; + + public static RefreshMode from(String type) { + return Enum.valueOf(RefreshMode.class, type.toUpperCase()); + } +} diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Fetch.java b/src/main/java/net/sf/jsqlparser/statement/select/Fetch.java index 1bf4c1eba..f4590d7df 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/Fetch.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/Fetch.java @@ -9,14 +9,19 @@ */ package net.sf.jsqlparser.statement.select; -import net.sf.jsqlparser.expression.*; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.JdbcParameter; +import net.sf.jsqlparser.expression.LongValue; import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class Fetch implements Serializable { private Expression expression = null; private boolean isFetchParamFirst = false; - private String fetchParam = "ROW"; + private final List fetchParameters = new ArrayList<>(); @Deprecated public long getRowCount() { @@ -46,8 +51,22 @@ public JdbcParameter getFetchJdbcParameter() { return expression instanceof JdbcParameter ? (JdbcParameter) expression : null; } + public Fetch addFetchParameter(String parameter) { + fetchParameters.add(parameter); + return this; + } + + public List getFetchParameters() { + return this.fetchParameters; + } + + @Deprecated public String getFetchParam() { - return fetchParam; + String parameterStr = ""; + for (String p : fetchParameters) { + parameterStr += " " + p; + } + return parameterStr.trim(); } public boolean isFetchParamFirst() { @@ -59,30 +78,54 @@ public void setFetchJdbcParameter(JdbcParameter jdbc) { this.setExpression(jdbc); } + @Deprecated public void setFetchParam(String s) { - this.fetchParam = s; + fetchParameters.clear(); + if (s != null) { + fetchParameters.addAll(Arrays.asList(s.trim().split("\\s+"))); + } } public void setFetchParamFirst(boolean b) { this.isFetchParamFirst = b; } + public StringBuilder appendTo(StringBuilder builder) { + builder.append(" FETCH"); + if (isFetchParamFirst) { + builder.append(" FIRST"); + } else { + builder.append(" NEXT"); + } + + if (expression != null) { + builder.append(" ").append(expression); + } + + for (String s : fetchParameters) { + builder.append(" ").append(s); + } + return builder; + } + @Override public String toString() { - return " FETCH " + (isFetchParamFirst ? "FIRST" : "NEXT") + " " + expression.toString() - + " " + fetchParam + " ONLY"; + return appendTo(new StringBuilder()).toString(); } + @Deprecated public Fetch withRowCount(long rowCount) { this.setRowCount(rowCount); return this; } + @Deprecated public Fetch withFetchJdbcParameter(JdbcParameter fetchJdbcParameter) { this.setFetchJdbcParameter(fetchJdbcParameter); return this; } + @Deprecated public Fetch withFetchParam(String fetchParam) { this.setFetchParam(fetchParam); return this; diff --git a/src/main/java/net/sf/jsqlparser/statement/select/ForMode.java b/src/main/java/net/sf/jsqlparser/statement/select/ForMode.java new file mode 100644 index 000000000..a58233ed1 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/statement/select/ForMode.java @@ -0,0 +1,34 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2023 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement.select; + +/** + * @author jxnu-liguobin + */ +public enum ForMode { + + UPDATE("UPDATE"), + + SHARE("SHARE"), + + NO_KEY_UPDATE("NO KEY UPDATE"), + + KEY_SHARE("KEY SHARE"); + + private final String value; + + public String getValue() { + return value; + } + + ForMode(String s) { + this.value = s; + } +} diff --git a/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java b/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java index 4aa45bbf0..d052ad465 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java @@ -9,10 +9,6 @@ */ package net.sf.jsqlparser.statement.select; -import net.sf.jsqlparser.expression.Expression; -import net.sf.jsqlparser.expression.operators.relational.ExpressionList; -import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList; - import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -20,10 +16,15 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList; public class GroupByElement implements Serializable { private ExpressionList groupByExpressions = new ExpressionList(); private List groupingSets = new ArrayList<>(); + // postgres rollup is an ExpressionList + private boolean mysqlWithRollup = false; public boolean isUsingBrackets() { return groupByExpressions.isUsingBrackets(); @@ -90,6 +91,10 @@ public String toString() { b.append(")"); } + if (isMysqlWithRollup()) { + b.append(" WITH ROLLUP"); + } + return b.toString(); } @@ -126,4 +131,13 @@ public GroupByElement addGroupingSets(Collection groupingSets) collection.addAll(groupingSets); return this.withGroupingSets(collection); } + + public boolean isMysqlWithRollup() { + return mysqlWithRollup; + } + + public GroupByElement setMysqlWithRollup(boolean mysqlWithRollup) { + this.mysqlWithRollup = mysqlWithRollup; + return this; + } } diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Join.java b/src/main/java/net/sf/jsqlparser/statement/select/Join.java index efaa3e6c7..d057a5381 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/Join.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/Join.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Optional; +@SuppressWarnings({"PMD.CyclomaticComplexity"}) public class Join extends ASTNodeAccessImpl { private boolean outer = false; @@ -39,6 +40,8 @@ public class Join extends ASTNodeAccessImpl { private final LinkedList usingColumns = new LinkedList<>(); private KSQLJoinWindow joinWindow; + private JoinHint joinHint = null; + public boolean isSimple() { return simple; } @@ -377,6 +380,15 @@ public void setJoinWindow(KSQLJoinWindow joinWindow) { this.joinWindow = joinWindow; } + public JoinHint getJoinHint() { + return joinHint; + } + + public Join setJoinHint(JoinHint joinHint) { + this.joinHint = joinHint; + return this; + } + @Override @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"}) public String toString() { @@ -418,6 +430,9 @@ public String toString() { } else if (isApply()) { builder.append("APPLY "); } else { + if (joinHint != null) { + builder.append(joinHint).append(" "); + } builder.append("JOIN "); } diff --git a/src/main/java/net/sf/jsqlparser/statement/select/JoinHint.java b/src/main/java/net/sf/jsqlparser/statement/select/JoinHint.java new file mode 100644 index 000000000..099f73042 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/statement/select/JoinHint.java @@ -0,0 +1,31 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2023 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement.select; + +/** + * Hints (Transact-SQL) - Join + * + * @link Hints + * (Transact-SQL) - Join + */ + +public class JoinHint { + private final String keyword; + + public JoinHint(String keyword) { + this.keyword = keyword; + } + + @Override + public String toString() { + return keyword; + } +} diff --git a/src/main/java/net/sf/jsqlparser/statement/select/OrderByElement.java b/src/main/java/net/sf/jsqlparser/statement/select/OrderByElement.java index acba858fd..36597fde4 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/OrderByElement.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/OrderByElement.java @@ -9,9 +9,8 @@ */ package net.sf.jsqlparser.statement.select; -import net.sf.jsqlparser.expression.Expression; - import java.io.Serializable; +import net.sf.jsqlparser.expression.Expression; public class OrderByElement implements Serializable { @@ -24,6 +23,8 @@ public static NullOrdering from(String ordering) { } private Expression expression; + // postgres rollup is an ExpressionList + private boolean mysqlWithRollup = false; private boolean asc = true; private boolean ascDescPresent = false; private NullOrdering nullOrdering; @@ -79,6 +80,9 @@ public String toString() { b.append(' '); b.append(nullOrdering == NullOrdering.NULLS_FIRST ? "NULLS FIRST" : "NULLS LAST"); } + if (isMysqlWithRollup()) { + b.append(" WITH ROLLUP"); + } return b.toString(); } @@ -106,4 +110,13 @@ public E getExpression(Class type) { return type.cast(getExpression()); } + public boolean isMysqlWithRollup() { + return mysqlWithRollup; + } + + public OrderByElement setMysqlWithRollup(boolean mysqlWithRollup) { + this.mysqlWithRollup = mysqlWithRollup; + return this; + } + } diff --git a/src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java b/src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java index 5e322c52f..72a4e530c 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java @@ -9,12 +9,7 @@ */ package net.sf.jsqlparser.statement.select; -import net.sf.jsqlparser.expression.Alias; -import net.sf.jsqlparser.expression.Expression; -import net.sf.jsqlparser.expression.OracleHierarchicalExpression; -import net.sf.jsqlparser.expression.OracleHint; -import net.sf.jsqlparser.expression.WindowDefinition; -import net.sf.jsqlparser.schema.Table; +import static java.util.stream.Collectors.joining; import java.util.ArrayList; import java.util.Arrays; @@ -23,8 +18,12 @@ import java.util.Iterator; import java.util.List; import java.util.Optional; - -import static java.util.stream.Collectors.joining; +import net.sf.jsqlparser.expression.Alias; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.OracleHierarchicalExpression; +import net.sf.jsqlparser.expression.OracleHint; +import net.sf.jsqlparser.expression.WindowDefinition; +import net.sf.jsqlparser.schema.Table; @SuppressWarnings({"PMD.CyclomaticComplexity"}) public class PlainSelect extends Select { @@ -46,7 +45,7 @@ public class PlainSelect extends Select { private Top top; private OracleHierarchicalExpression oracleHierarchical = null; private OracleHint oracleHint = null; - private boolean forUpdate = false; + private ForMode forMode = null; private Table forUpdateTable = null; private boolean skipLocked; private Wait wait; @@ -312,12 +311,12 @@ public void setOracleHierarchical(OracleHierarchicalExpression oracleHierarchica this.oracleHierarchical = oracleHierarchical; } - public boolean isForUpdate() { - return forUpdate; + public ForMode getForMode() { + return forMode; } - public void setForUpdate(boolean forUpdate) { - this.forUpdate = forUpdate; + public void setForMode(ForMode forMode) { + this.forMode = forMode; } public Table getForUpdateTable() { @@ -486,8 +485,9 @@ public StringBuilder appendSelectBodyTo(StringBuilder builder) { if (emitChanges) { builder.append(" EMIT CHANGES"); } - if (isForUpdate()) { - builder.append(" FOR UPDATE"); + if (getForMode() != null) { + builder.append(" FOR "); + builder.append(getForMode().getValue()); if (forUpdateTable != null) { builder.append(" OF ").append(forUpdateTable); @@ -620,8 +620,8 @@ public PlainSelect withOracleSiblings(boolean oracleSiblings) { return this; } - public PlainSelect withForUpdate(boolean forUpdate) { - this.setForUpdate(forUpdate); + public PlainSelect withForMode(ForMode forMode) { + this.setForMode(forMode); return this; } diff --git a/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitor.java b/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitor.java index 1d3643f50..04a6b9d9e 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitor.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitor.java @@ -22,4 +22,6 @@ public interface SelectVisitor { void visit(Values aThis); void visit(LateralSubSelect lateralSubSelect); + + void visit(TableStatement tableStatement); } diff --git a/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitorAdapter.java index 91c6f32c2..a349a9005 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitorAdapter.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/SelectVisitorAdapter.java @@ -41,4 +41,9 @@ public void visit(Values aThis) { public void visit(LateralSubSelect lateralSubSelect) { } + + @Override + public void visit(TableStatement tableStatement) { + + } } diff --git a/src/main/java/net/sf/jsqlparser/statement/select/TableStatement.java b/src/main/java/net/sf/jsqlparser/statement/select/TableStatement.java new file mode 100644 index 000000000..b665b16a6 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/statement/select/TableStatement.java @@ -0,0 +1,59 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2019 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement.select; + +import net.sf.jsqlparser.schema.Table; + +/** + * @see `TABLE table_name [ORDER + * BY column_name] [LIMIT number [OFFSET number]]` Union not currently supported + * + * @author jxnu-liguobin + */ +public class TableStatement extends Select { + + private Table table; + + public Table getTable() { + return table; + } + + public void setTable(Table table) { + this.table = table; + } + + @Override + public StringBuilder appendSelectBodyTo(StringBuilder builder) { + builder.append("TABLE ").append(table.getName()); + return builder; + } + + @SuppressWarnings({"PMD.CyclomaticComplexity"}) + @Override + public StringBuilder appendTo(StringBuilder builder) { + + appendSelectBodyTo(builder); + + builder.append(orderByToString(false, orderByElements)); + + if (limit != null) { + builder.append(limit); + } + if (offset != null) { + builder.append(offset); + } + return builder; + } + + @Override + public void accept(SelectVisitor selectVisitor) { + selectVisitor.visit(this); + } +} diff --git a/src/main/java/net/sf/jsqlparser/statement/update/Update.java b/src/main/java/net/sf/jsqlparser/statement/update/Update.java index c4975f503..0a6224d76 100644 --- a/src/main/java/net/sf/jsqlparser/statement/update/Update.java +++ b/src/main/java/net/sf/jsqlparser/statement/update/Update.java @@ -292,6 +292,9 @@ public String toString() { } } b.append("UPDATE "); + if (oracleHint != null) { + b.append(oracleHint).append(" "); + } if (modifierPriority != null) { b.append(modifierPriority.name()).append(" "); } diff --git a/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java b/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java index 7c6fca540..84299c0fb 100644 --- a/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java +++ b/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java @@ -72,7 +72,7 @@ public void add(Column column, Expression value) { * @param column */ public void add(Column column) { - if (columns.size() < 2 && !(columns instanceof ParenthesedExpressionList)) { + if (!columns.isEmpty() && !(columns instanceof ParenthesedExpressionList)) { columns = new ParenthesedExpressionList<>(columns); } columns.add(column); @@ -85,7 +85,7 @@ public void add(Column column) { * @param expression */ public void add(Expression expression) { - if (values.size() < 2 && !(values instanceof ParenthesedExpressionList)) { + if (!values.isEmpty() && !(values instanceof ParenthesedExpressionList)) { values = new ParenthesedExpressionList<>(values); } values.add(expression); diff --git a/src/main/java/net/sf/jsqlparser/util/AddAliasesVisitor.java b/src/main/java/net/sf/jsqlparser/util/AddAliasesVisitor.java index 3303c091f..58ca4326f 100644 --- a/src/main/java/net/sf/jsqlparser/util/AddAliasesVisitor.java +++ b/src/main/java/net/sf/jsqlparser/util/AddAliasesVisitor.java @@ -9,6 +9,8 @@ */ package net.sf.jsqlparser.util; +import java.util.LinkedList; +import java.util.List; import net.sf.jsqlparser.expression.Alias; import net.sf.jsqlparser.statement.select.LateralSubSelect; import net.sf.jsqlparser.statement.select.ParenthesedSelect; @@ -18,12 +20,10 @@ import net.sf.jsqlparser.statement.select.SelectItemVisitor; import net.sf.jsqlparser.statement.select.SelectVisitor; import net.sf.jsqlparser.statement.select.SetOperationList; +import net.sf.jsqlparser.statement.select.TableStatement; import net.sf.jsqlparser.statement.select.Values; import net.sf.jsqlparser.statement.select.WithItem; -import java.util.LinkedList; -import java.util.List; - /** * Add aliases to every column and expression selected by a select - statement. Existing aliases are * recognized and preserved. This class standard uses a prefix of A and a counter to generate new @@ -112,4 +112,9 @@ public void visit(Values aThis) { public void visit(LateralSubSelect lateralSubSelect) { lateralSubSelect.getSelect().accept(this); } + + @Override + public void visit(TableStatement tableStatement) { + throw new UnsupportedOperationException("Not supported yet."); + } } diff --git a/src/main/java/net/sf/jsqlparser/util/ConnectExpressionsVisitor.java b/src/main/java/net/sf/jsqlparser/util/ConnectExpressionsVisitor.java index 479bc3c3e..46b746f0a 100644 --- a/src/main/java/net/sf/jsqlparser/util/ConnectExpressionsVisitor.java +++ b/src/main/java/net/sf/jsqlparser/util/ConnectExpressionsVisitor.java @@ -9,6 +9,8 @@ */ package net.sf.jsqlparser.util; +import java.util.LinkedList; +import java.util.List; import net.sf.jsqlparser.expression.Alias; import net.sf.jsqlparser.expression.BinaryExpression; import net.sf.jsqlparser.statement.select.LateralSubSelect; @@ -19,12 +21,10 @@ import net.sf.jsqlparser.statement.select.SelectItemVisitor; import net.sf.jsqlparser.statement.select.SelectVisitor; import net.sf.jsqlparser.statement.select.SetOperationList; +import net.sf.jsqlparser.statement.select.TableStatement; import net.sf.jsqlparser.statement.select.Values; import net.sf.jsqlparser.statement.select.WithItem; -import java.util.LinkedList; -import java.util.List; - /** * Connect all selected expressions with a binary expression. Out of select a,b from table one gets * select a || b as expr from table. The type of binary expression is set by overwriting this class @@ -103,4 +103,8 @@ public void visit(Values aThis) { throw new UnsupportedOperationException("Not supported yet."); } + @Override + public void visit(TableStatement tableStatement) { + throw new UnsupportedOperationException("Not supported yet."); + } } diff --git a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java index d8fc4cf7b..7a94ceff7 100644 --- a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java +++ b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java @@ -9,6 +9,11 @@ */ package net.sf.jsqlparser.util; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.AllValue; import net.sf.jsqlparser.expression.AnalyticExpression; @@ -78,6 +83,9 @@ import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.conditional.XorExpression; import net.sf.jsqlparser.expression.operators.relational.Between; +import net.sf.jsqlparser.expression.operators.relational.ContainedBy; +import net.sf.jsqlparser.expression.operators.relational.Contains; +import net.sf.jsqlparser.expression.operators.relational.DoubleAnd; import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; @@ -98,6 +106,8 @@ import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo; import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator; import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression; +import net.sf.jsqlparser.expression.operators.relational.TSQLLeftJoin; +import net.sf.jsqlparser.expression.operators.relational.TSQLRightJoin; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; @@ -141,6 +151,7 @@ import net.sf.jsqlparser.statement.grant.Grant; import net.sf.jsqlparser.statement.insert.Insert; import net.sf.jsqlparser.statement.merge.Merge; +import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement; import net.sf.jsqlparser.statement.select.AllColumns; import net.sf.jsqlparser.statement.select.AllTableColumns; import net.sf.jsqlparser.statement.select.FromItemVisitor; @@ -156,6 +167,7 @@ import net.sf.jsqlparser.statement.select.SelectVisitor; import net.sf.jsqlparser.statement.select.SetOperationList; import net.sf.jsqlparser.statement.select.TableFunction; +import net.sf.jsqlparser.statement.select.TableStatement; import net.sf.jsqlparser.statement.select.Values; import net.sf.jsqlparser.statement.select.WithItem; import net.sf.jsqlparser.statement.show.ShowIndexStatement; @@ -164,12 +176,6 @@ import net.sf.jsqlparser.statement.update.Update; import net.sf.jsqlparser.statement.upsert.Upsert; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - /** * Find all used tables within an select statement. * @@ -470,6 +476,21 @@ public void visit(NotEqualsTo notEqualsTo) { visitBinaryExpression(notEqualsTo); } + @Override + public void visit(DoubleAnd doubleAnd) { + visitBinaryExpression(doubleAnd); + } + + @Override + public void visit(Contains contains) { + visitBinaryExpression(contains); + } + + @Override + public void visit(ContainedBy containedBy) { + visitBinaryExpression(containedBy); + } + @Override public void visit(NullValue nullValue) { @@ -671,6 +692,11 @@ public void visit(LateralSubSelect lateralSubSelect) { lateralSubSelect.getSelect().accept((SelectVisitor) this); } + @Override + public void visit(TableStatement tableStatement) { + tableStatement.getTable().accept(this); + } + /** * Initializes table names collector. Important is the usage of Column instances to find table * names. This is only allowed for expression parsing, where a better place for tablenames could @@ -966,6 +992,11 @@ public void visit(AlterView alterView) { throw new UnsupportedOperationException(NOT_SUPPORTED_YET); } + @Override + public void visit(RefreshMaterializedViewStatement materializedView) { + visit(materializedView.getView()); + } + @Override public void visit(TimeKeyExpression timeKeyExpression) { @@ -1036,7 +1067,9 @@ public void visit(DescribeStatement describe) { @Override public void visit(ExplainStatement explain) { - explain.getStatement().accept((StatementVisitor) this); + if (explain.getStatement() != null) { + explain.getStatement().accept((StatementVisitor) this); + } } @Override @@ -1115,6 +1148,16 @@ public void visit(ShowTablesStatement showTables) { "Finding tables from ShowTablesStatement is not supported"); } + @Override + public void visit(TSQLLeftJoin tsqlLeftJoin) { + visitBinaryExpression(tsqlLeftJoin); + } + + @Override + public void visit(TSQLRightJoin tsqlRightJoin) { + visitBinaryExpression(tsqlRightJoin); + } + @Override public void visit(VariableAssignment var) { var.getVariable().accept(this); diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/CreateIndexDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/CreateIndexDeParser.java index 0f2aae236..a82f478d7 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/CreateIndexDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/CreateIndexDeParser.java @@ -32,12 +32,21 @@ public void deParse(CreateIndex createIndex) { } buffer.append("INDEX "); + if (createIndex.isUsingIfNotExists()) { + buffer.append("IF NOT EXISTS "); + } buffer.append(index.getName()); + + String using = index.getUsing(); + if (using != null && createIndex.isIndexTypeBeforeOn()) { + buffer.append(" USING "); + buffer.append(using); + } + buffer.append(" ON "); buffer.append(createIndex.getTable().getFullyQualifiedName()); - String using = index.getUsing(); - if (using != null) { + if (using != null && !createIndex.isIndexTypeBeforeOn()) { buffer.append(" USING "); buffer.append(using); } @@ -45,7 +54,9 @@ public void deParse(CreateIndex createIndex) { if (index.getColumnsNames() != null) { buffer.append(" ("); buffer.append(index.getColumnWithParams().stream() - .map(cp -> cp.columnName + (cp.getParams() != null ? " " + String.join(" ", cp.getParams()) : "")) + .map(cp -> cp.columnName + + (cp.getParams() != null ? " " + String.join(" ", cp.getParams()) + : "")) .collect(joining(", "))); buffer.append(")"); } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/CreateViewDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/CreateViewDeParser.java index 13973b06e..1f5662e68 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/CreateViewDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/CreateViewDeParser.java @@ -67,7 +67,13 @@ public void deParse(CreateView createView) { buffer.append(" AUTO REFRESH ").append(createView.getAutoRefresh().name()); } if (createView.getColumnNames() != null) { - buffer.append(PlainSelect.getStringList(createView.getColumnNames(), true, true)); + buffer.append("("); + buffer.append(createView.getColumnNames()); + buffer.append(")"); + } + if (createView.getViewCommentOptions() != null) { + buffer.append( + PlainSelect.getStringList(createView.getViewCommentOptions(), false, false)); } buffer.append(" AS "); diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/DeleteDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/DeleteDeParser.java index b97794af4..ef4d0922d 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/DeleteDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/DeleteDeParser.java @@ -48,6 +48,9 @@ public void deParse(Delete delete) { } } buffer.append("DELETE"); + if (delete.getOracleHint() != null) { + buffer.append(delete.getOracleHint()).append(" "); + } if (delete.getModifierPriority() != null) { buffer.append(" ").append(delete.getModifierPriority()); } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java index 383c8802a..494444348 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java @@ -78,6 +78,9 @@ import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.conditional.XorExpression; import net.sf.jsqlparser.expression.operators.relational.Between; +import net.sf.jsqlparser.expression.operators.relational.ContainedBy; +import net.sf.jsqlparser.expression.operators.relational.Contains; +import net.sf.jsqlparser.expression.operators.relational.DoubleAnd; import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; @@ -100,6 +103,8 @@ import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator; import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression; import net.sf.jsqlparser.expression.operators.relational.SupportsOldOracleJoinSyntax; +import net.sf.jsqlparser.expression.operators.relational.TSQLLeftJoin; +import net.sf.jsqlparser.expression.operators.relational.TSQLRightJoin; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.select.AllColumns; @@ -247,6 +252,9 @@ public void visit(InExpression inExpression) { .getOldOracleJoinSyntax() == SupportsOldOracleJoinSyntax.ORACLE_JOIN_RIGHT) { buffer.append("(+)"); } + if (inExpression.isGlobal()) { + buffer.append(" GLOBAL"); + } if (inExpression.isNot()) { buffer.append(" NOT"); } @@ -399,6 +407,25 @@ public void visit(NotEqualsTo notEqualsTo) { } + @Override + public void visit(DoubleAnd doubleAnd) { + visitOldOracleJoinBinaryExpression(doubleAnd, " " + doubleAnd.getStringExpression() + " "); + + } + + @Override + public void visit(Contains contains) { + visitOldOracleJoinBinaryExpression(contains, " " + contains.getStringExpression() + " "); + + } + + @Override + public void visit(ContainedBy containedBy) { + visitOldOracleJoinBinaryExpression(containedBy, + " " + containedBy.getStringExpression() + " "); + + } + @Override public void visit(NullValue nullValue) { buffer.append(nullValue.toString()); @@ -1068,4 +1095,15 @@ public void visit(GeometryDistance geometryDistance) { visitOldOracleJoinBinaryExpression(geometryDistance, " " + geometryDistance.getStringExpression() + " "); } + + @Override + public void visit(TSQLLeftJoin tsqlLeftJoin) { + visitBinaryExpression(tsqlLeftJoin, " *= "); + } + + @Override + public void visit(TSQLRightJoin tsqlRightJoin) { + visitBinaryExpression(tsqlRightJoin, " =* "); + } + } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/GroupByDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/GroupByDeParser.java index 3c5cedf10..694a97d38 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/GroupByDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/GroupByDeParser.java @@ -45,5 +45,9 @@ public void deParse(GroupByElement groupBy) { } buffer.append(")"); } + + if (groupBy.isMysqlWithRollup()) { + buffer.append(" WITH ROLLUP"); + } } } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java index 84d473f76..dec9f6c0a 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java @@ -54,6 +54,9 @@ public void deParse(Insert insert) { if (insert.getModifierPriority() != null) { buffer.append(insert.getModifierPriority()).append(" "); } + if (insert.getOracleHint() != null) { + buffer.append(insert.getOracleHint()).append(" "); + } if (insert.isModifierIgnore()) { buffer.append("IGNORE "); } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/OrderByDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/OrderByDeParser.java index 1586bc6ed..8eb137051 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/OrderByDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/OrderByDeParser.java @@ -11,7 +11,6 @@ import java.util.Iterator; import java.util.List; - import net.sf.jsqlparser.expression.ExpressionVisitor; import net.sf.jsqlparser.statement.select.OrderByElement; @@ -58,9 +57,13 @@ public void deParseElement(OrderByElement orderBy) { } if (orderBy.getNullOrdering() != null) { buffer.append(' '); - buffer.append(orderBy.getNullOrdering() == OrderByElement.NullOrdering.NULLS_FIRST ? "NULLS FIRST" + buffer.append(orderBy.getNullOrdering() == OrderByElement.NullOrdering.NULLS_FIRST + ? "NULLS FIRST" : "NULLS LAST"); } + if (orderBy.isMysqlWithRollup()) { + buffer.append(" WITH ROLLUP"); + } } void setExpressionVisitor(ExpressionVisitor expressionVisitor) { diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/RefreshMaterializedViewStatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/RefreshMaterializedViewStatementDeParser.java new file mode 100644 index 000000000..0646a65fe --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/util/deparser/RefreshMaterializedViewStatementDeParser.java @@ -0,0 +1,53 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2019 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.util.deparser; + +import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement; + +/** + * @author jxnu-liguobin + */ + +public class RefreshMaterializedViewStatementDeParser + extends AbstractDeParser { + + public RefreshMaterializedViewStatementDeParser(StringBuilder buffer) { + super(buffer); + } + + @SuppressWarnings("PMD.SwitchStmtsShouldHaveDefault") + @Override + public void deParse(RefreshMaterializedViewStatement view) { + buffer.append("REFRESH MATERIALIZED VIEW "); + if (view.getRefreshMode() == null) { + if (view.isConcurrently()) { + buffer.append("CONCURRENTLY "); + } + buffer.append(view.getView()); + return; + } + switch (view.getRefreshMode()) { + case WITH_DATA: + if (view.isConcurrently()) { + buffer.append("CONCURRENTLY "); + } + buffer.append(view.getView()); + buffer.append(" WITH DATA"); + break; + case WITH_NO_DATA: + buffer.append(view.getView()); + if (view.isConcurrently()) { + buffer.append(" WITH NO DATA"); + } + break; + } + } + +} diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java index 0ba071794..a6b718baf 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java @@ -9,6 +9,10 @@ */ package net.sf.jsqlparser.util.deparser; +import static java.util.stream.Collectors.joining; + +import java.util.Iterator; +import java.util.List; import net.sf.jsqlparser.expression.Alias; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.ExpressionVisitor; @@ -40,16 +44,12 @@ import net.sf.jsqlparser.statement.select.SetOperationList; import net.sf.jsqlparser.statement.select.Skip; import net.sf.jsqlparser.statement.select.TableFunction; +import net.sf.jsqlparser.statement.select.TableStatement; import net.sf.jsqlparser.statement.select.Top; import net.sf.jsqlparser.statement.select.UnPivot; import net.sf.jsqlparser.statement.select.Values; import net.sf.jsqlparser.statement.select.WithItem; -import java.util.Iterator; -import java.util.List; - -import static java.util.stream.Collectors.joining; - @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"}) public class SelectDeParser extends AbstractDeParser implements SelectVisitor, SelectItemVisitor, FromItemVisitor, PivotVisitor { @@ -268,8 +268,10 @@ public void visit(PlainSelect plainSelect) { buffer.append(plainSelect.getWindowDefinitions().stream() .map(WindowDefinition::toString).collect(joining(", "))); } - if (plainSelect.isForUpdate()) { - buffer.append(" FOR UPDATE"); + if (plainSelect.getForMode() != null) { + buffer.append(" FOR "); + buffer.append(plainSelect.getForMode().getValue()); + if (plainSelect.getForUpdateTable() != null) { buffer.append(" OF ").append(plainSelect.getForUpdateTable()); } @@ -419,16 +421,19 @@ public void visit(Offset offset) { } public void visit(Fetch fetch) { - // FETCH (FIRST | NEXT) row_count (ROW | ROWS) ONLY buffer.append(" FETCH "); if (fetch.isFetchParamFirst()) { buffer.append("FIRST "); } else { buffer.append("NEXT "); } - fetch.getExpression().accept(expressionVisitor); - buffer.append(" ").append(fetch.getFetchParam()).append(" ONLY"); + if (fetch.getExpression() != null) { + fetch.getExpression().accept(expressionVisitor); + } + for (String p : fetch.getFetchParameters()) { + buffer.append(" ").append(p); + } } public ExpressionVisitor getExpressionVisitor() { @@ -478,6 +483,9 @@ public void deparseJoin(Join join) { } else if (join.isApply()) { buffer.append(" APPLY "); } else { + if (join.getJoinHint() != null) { + buffer.append(" ").append(join.getJoinHint()); + } buffer.append(" JOIN "); } @@ -583,6 +591,11 @@ public void visit(LateralSubSelect lateralSubSelect) { visit((ParenthesedSelect) lateralSubSelect); } + @Override + public void visit(TableStatement tableStatement) { + new TableStatementDeParser(expressionVisitor, buffer).deParse(tableStatement); + } + @Override public void visit(TableFunction tableFunction) { buffer.append(tableFunction.toString()); diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java index e5833c433..f5326ae41 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java @@ -9,6 +9,9 @@ */ package net.sf.jsqlparser.util.deparser; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; import net.sf.jsqlparser.statement.Block; import net.sf.jsqlparser.statement.Commit; import net.sf.jsqlparser.statement.CreateFunctionalStatement; @@ -50,6 +53,7 @@ import net.sf.jsqlparser.statement.merge.Merge; import net.sf.jsqlparser.statement.merge.MergeInsert; import net.sf.jsqlparser.statement.merge.MergeUpdate; +import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.WithItem; import net.sf.jsqlparser.statement.show.ShowIndexStatement; @@ -58,10 +62,6 @@ import net.sf.jsqlparser.statement.update.Update; import net.sf.jsqlparser.statement.upsert.Upsert; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Collectors; - public class StatementDeParser extends AbstractDeParser implements StatementVisitor { private final ExpressionDeParser expressionDeParser; @@ -104,6 +104,11 @@ public void visit(CreateView createView) { createViewDeParser.deParse(createView); } + @Override + public void visit(RefreshMaterializedViewStatement materializedViewStatement) { + new RefreshMaterializedViewStatementDeParser(buffer).deParse(materializedViewStatement); + } + @Override public void visit(AlterView alterView) { AlterViewDeParser alterViewDeParser = new AlterViewDeParser(buffer); @@ -210,15 +215,18 @@ public void visit(Merge merge) { } } - buffer.append("MERGE INTO "); + buffer.append("MERGE "); + if (merge.getOracleHint() != null) { + buffer.append(merge.getOracleHint()).append(" "); + } + buffer.append("INTO "); merge.getTable().accept(selectDeParser); buffer.append(" USING "); merge.getFromItem().accept(selectDeParser); - buffer.append(" ON ("); + buffer.append(" ON "); merge.getOnCondition().accept(expressionDeParser); - buffer.append(")"); MergeInsert mergeInsert = merge.getMergeInsert(); MergeUpdate mergeUpdate = merge.getMergeUpdate(); @@ -227,7 +235,12 @@ public void visit(Merge merge) { } if (mergeUpdate != null) { - buffer.append(" WHEN MATCHED THEN UPDATE SET "); + buffer.append(" WHEN MATCHED"); + if (mergeUpdate.getAndPredicate() != null) { + buffer.append(" AND "); + mergeUpdate.getAndPredicate().accept(expressionDeParser); + } + buffer.append(" THEN UPDATE SET "); deparseUpdateSets(mergeUpdate.getUpdateSets(), buffer, expressionDeParser); if (mergeUpdate.getWhereCondition() != null) { @@ -244,10 +257,19 @@ public void visit(Merge merge) { if (!merge.isInsertFirst() && mergeInsert != null) { deparseMergeInsert(mergeInsert); } + + if (merge.getOutputClause() != null) { + merge.getOutputClause().appendTo(buffer); + } } private void deparseMergeInsert(MergeInsert mergeInsert) { - buffer.append(" WHEN NOT MATCHED THEN INSERT "); + buffer.append(" WHEN NOT MATCHED"); + if (mergeInsert.getAndPredicate() != null) { + buffer.append(" AND "); + mergeInsert.getAndPredicate().accept(expressionDeParser); + } + buffer.append(" THEN INSERT "); if (mergeInsert.getColumns() != null) { mergeInsert.getColumns().accept(expressionDeParser); } @@ -324,19 +346,25 @@ public void visit(Comment comment) { @Override public void visit(DescribeStatement describe) { - buffer.append("DESCRIBE "); + buffer.append(describe.getDescribeType()); + buffer.append(" "); buffer.append(describe.getTable()); } @Override public void visit(ExplainStatement explain) { buffer.append("EXPLAIN "); - if (explain.getOptions() != null) { + if (explain.getTable() != null) { + buffer.append(explain.getTable()); + } else if (explain.getOptions() != null) { buffer.append(explain.getOptions().values().stream() .map(ExplainStatement.Option::formatOption).collect(Collectors.joining(" "))); buffer.append(" "); } - explain.getStatement().accept(this); + if (explain.getStatement() != null) { + explain.getStatement().accept(this); + + } } @Override diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/TableStatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/TableStatementDeParser.java new file mode 100644 index 000000000..962849c6e --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/util/deparser/TableStatementDeParser.java @@ -0,0 +1,98 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2019 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.util.deparser; + +import net.sf.jsqlparser.expression.ExpressionVisitor; +import net.sf.jsqlparser.statement.select.LateralSubSelect; +import net.sf.jsqlparser.statement.select.Offset; +import net.sf.jsqlparser.statement.select.ParenthesedSelect; +import net.sf.jsqlparser.statement.select.PlainSelect; +import net.sf.jsqlparser.statement.select.SelectVisitor; +import net.sf.jsqlparser.statement.select.SetOperationList; +import net.sf.jsqlparser.statement.select.TableStatement; +import net.sf.jsqlparser.statement.select.Values; +import net.sf.jsqlparser.statement.select.WithItem; + +/** + * @author jxnu-liguobin + */ +public class TableStatementDeParser extends AbstractDeParser + implements SelectVisitor { + + private final ExpressionVisitor expressionVisitor; + + public TableStatementDeParser(ExpressionVisitor expressionVisitor, StringBuilder buffer) { + super(buffer); + this.expressionVisitor = expressionVisitor; + } + + @Override + public void deParse(TableStatement tableStatement) { + tableStatement.accept(this); + } + + public void visit(Offset offset) { + buffer.append(" OFFSET "); + offset.getOffset().accept(expressionVisitor); + if (offset.getOffsetParam() != null) { + buffer.append(" ").append(offset.getOffsetParam()); + } + + } + + @Override + public void visit(ParenthesedSelect parenthesedSelect) { + + } + + @Override + public void visit(PlainSelect plainSelect) { + + } + + @Override + public void visit(SetOperationList setOpList) { + + } + + @Override + public void visit(WithItem withItem) { + + } + + @Override + public void visit(Values aThis) { + + } + + @Override + public void visit(LateralSubSelect lateralSubSelect) { + + } + + @Override + public void visit(TableStatement tableStatement) { + buffer.append("TABLE "); + buffer.append(tableStatement.getTable()); + if (tableStatement.getOrderByElements() != null) { + new OrderByDeParser(expressionVisitor, buffer) + .deParse(tableStatement.getOrderByElements()); + } + + if (tableStatement.getLimit() != null) { + new LimitDeparser(expressionVisitor, buffer).deParse(tableStatement.getLimit()); + } + if (tableStatement.getOffset() != null) { + visit(tableStatement.getOffset()); + } + + // TODO UNION + } +} diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java index 4f8affbeb..0ba4003c4 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java @@ -48,6 +48,9 @@ public void deParse(Update update) { } } buffer.append("UPDATE "); + if (update.getOracleHint() != null) { + buffer.append(update.getOracleHint()).append(" "); + } if (update.getModifierPriority() != null) { buffer.append(update.getModifierPriority()).append(" "); } diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java index 04c9a1277..3ada0ec28 100644 --- a/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java +++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java @@ -38,13 +38,14 @@ public class FeaturesAllowed implements FeatureSetValidation, ModifyableFeatureS Feature.jdbcParameter, Feature.jdbcNamedParameter).unmodifyable(); - public static final FeaturesAllowed EXPRESSIONS = new FeaturesAllowed("EXPRESSIONS", Feature.exprLike, - Feature.exprSimilarTo); + public static final FeaturesAllowed EXPRESSIONS = + new FeaturesAllowed("EXPRESSIONS", Feature.exprLike, + Feature.exprSimilarTo); /** * all {@link Feature}' within SQL SELECT without modification features like - * {@link Feature#selectInto}, but jdbc-features like - * {@link Feature#jdbcParameter} and {@link Feature#jdbcNamedParameter} + * {@link Feature#selectInto}, but jdbc-features like {@link Feature#jdbcParameter} and + * {@link Feature#jdbcNamedParameter} */ public static final FeaturesAllowed SELECT = new FeaturesAllowed("SELECT", // select features @@ -86,22 +87,25 @@ public class FeaturesAllowed implements FeatureSetValidation, ModifyableFeatureS Feature.distinctOn, Feature.orderBy, Feature.orderByNullOrdering, + Feature.tableStatement, Feature.function).unmodifyable(); /** - * all {@link Feature}' for SQL INSERT including {@link #SELECT} and - * {@link Feature#selectInto} + * all {@link Feature}' for SQL INSERT including {@link #SELECT} and {@link Feature#selectInto} */ - public static final FeaturesAllowed INSERT = new FeaturesAllowed("INSERT", Feature.insert, Feature.insertFromSelect, - Feature.insertModifierIgnore, Feature.insertModifierPriority, Feature.insertReturningAll, - Feature.insertReturningExpressionList, Feature.insertUseSet, - Feature.insertValues, Feature.selectInto).add(SELECT).unmodifyable(); + public static final FeaturesAllowed INSERT = + new FeaturesAllowed("INSERT", Feature.insert, Feature.insertFromSelect, + Feature.insertModifierIgnore, Feature.insertModifierPriority, + Feature.insertReturningAll, + Feature.insertReturningExpressionList, Feature.insertUseSet, + Feature.insertValues, Feature.selectInto).add(SELECT).unmodifyable(); /** * all {@link Feature}' for SQL UPDATE including {@link #SELECT} */ - public static final FeaturesAllowed UPDATE = new FeaturesAllowed("UPDATE", Feature.update, Feature.updateJoins, + public static final FeaturesAllowed UPDATE = new FeaturesAllowed("UPDATE", Feature.update, + Feature.updateJoins, Feature.updateFrom, Feature.updateLimit, Feature.updateOrderBy, Feature.updateReturning, Feature.updateUseSelect) .add(SELECT).unmodifyable(); @@ -109,55 +113,66 @@ public class FeaturesAllowed implements FeatureSetValidation, ModifyableFeatureS /** * all {@link Feature}' for SQL UPDATE including {@link #SELECT} */ - public static final FeaturesAllowed DELETE = new FeaturesAllowed("DELETE", Feature.delete, Feature.deleteJoin, - Feature.deleteLimit, Feature.deleteOrderBy, Feature.deleteTables, Feature.deleteReturningExpressionList, - Feature.truncate) - .add(SELECT).unmodifyable(); + public static final FeaturesAllowed DELETE = + new FeaturesAllowed("DELETE", Feature.delete, Feature.deleteJoin, + Feature.deleteLimit, Feature.deleteOrderBy, Feature.deleteTables, + Feature.deleteReturningExpressionList, + Feature.truncate) + .add(SELECT).unmodifyable(); /** * all {@link Feature}' for SQL MERGE other similar commands */ - public static final FeaturesAllowed MERGE = new FeaturesAllowed("MERGE", Feature.merge, Feature.upsert, - Feature.insertUseDuplicateKeyUpdate).unmodifyable(); + public static final FeaturesAllowed MERGE = + new FeaturesAllowed("MERGE", Feature.merge, Feature.upsert, + Feature.insertUseDuplicateKeyUpdate).unmodifyable(); /** * all DML {@link Feature}'s */ - public static final FeaturesAllowed DML = new FeaturesAllowed("DML").add(SELECT, INSERT, UPDATE, DELETE, MERGE) - .unmodifyable(); + public static final FeaturesAllowed DML = + new FeaturesAllowed("DML").add(SELECT, INSERT, UPDATE, DELETE, MERGE) + .unmodifyable(); - public static final FeaturesAllowed EXECUTE = new FeaturesAllowed("EXECUTE", Feature.execute).unmodifyable(); + public static final FeaturesAllowed EXECUTE = + new FeaturesAllowed("EXECUTE", Feature.execute).unmodifyable(); /** * all "CREATE" {@link Feature}'s */ public static final FeaturesAllowed CREATE = new FeaturesAllowed("CREATE", Feature.createIndex, - Feature.createSchema, Feature.createSequence, Feature.createTable, Feature.createTableUnlogged, + Feature.createSchema, Feature.createSequence, Feature.createTable, + Feature.createTableUnlogged, Feature.createTableCreateOptionStrings, Feature.createTableTableOptionStrings, - Feature.createTableIfNotExists, Feature.createTableRowMovement, Feature.createTableFromSelect, + Feature.createTableIfNotExists, Feature.createTableRowMovement, + Feature.createTableFromSelect, Feature.createTrigger, Feature.createView).unmodifyable(); /** * all "ALTER" {@link Feature}'s */ - public static final FeaturesAllowed ALTER = new FeaturesAllowed("ALTER", Feature.alterTable, Feature.alterSequence, - Feature.alterView, Feature.alterIndex) - .unmodifyable(); + public static final FeaturesAllowed ALTER = + new FeaturesAllowed("ALTER", Feature.alterTable, Feature.alterSequence, + Feature.alterView, Feature.alterIndex) + .unmodifyable(); /** * all "DROP" {@link Feature}'s */ - public static final FeaturesAllowed DROP = new FeaturesAllowed("DROP", Feature.drop, Feature.dropTable, - Feature.dropIndex, Feature.dropView, Feature.dropSchema, Feature.dropSequence, Feature.dropTableIfExists, - Feature.dropIndexIfExists, Feature.dropViewIfExists, Feature.dropSchemaIfExists, - Feature.dropSequenceIfExists) - .unmodifyable(); + public static final FeaturesAllowed DROP = + new FeaturesAllowed("DROP", Feature.drop, Feature.dropTable, + Feature.dropIndex, Feature.dropView, Feature.dropSchema, Feature.dropSequence, + Feature.dropTableIfExists, + Feature.dropIndexIfExists, Feature.dropViewIfExists, Feature.dropSchemaIfExists, + Feature.dropSequenceIfExists) + .unmodifyable(); /** * all DDL {@link Feature}'s */ - public static final FeaturesAllowed DDL = new FeaturesAllowed("DDL").add(CREATE, ALTER, DROP).unmodifyable(); + public static final FeaturesAllowed DDL = + new FeaturesAllowed("DDL").add(CREATE, ALTER, DROP).unmodifyable(); private Set names = new LinkedHashSet<>(); private Set features = new HashSet<>(); @@ -278,7 +293,8 @@ public ValidationException getMessage(Feature feature) { @Override public String getName() { - return names.isEmpty() ? FeatureSetValidation.super.getName() : names.stream().collect(Collectors.joining(SEPERATOR)); + return names.isEmpty() ? FeatureSetValidation.super.getName() + : names.stream().collect(Collectors.joining(SEPERATOR)); } @@ -289,7 +305,8 @@ public Set getFeatures() { private List collectNames(FeatureSetValidation fs) { String name = fs.getName(); - return Stream.of(name.split(SEPERATOR_REGEX)).map(String::trim).collect(Collectors.toList()); + return Stream.of(name.split(SEPERATOR_REGEX)).map(String::trim) + .collect(Collectors.toList()); } } diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/MariaDbVersion.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/MariaDbVersion.java index 185da5664..983adb4fd 100644 --- a/src/main/java/net/sf/jsqlparser/util/validation/feature/MariaDbVersion.java +++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/MariaDbVersion.java @@ -9,11 +9,10 @@ */ package net.sf.jsqlparser.util.validation.feature; -import net.sf.jsqlparser.parser.feature.Feature; - import java.util.Collections; import java.util.EnumSet; import java.util.Set; +import net.sf.jsqlparser.parser.feature.Feature; /** * Please add Features supported and place a link to public documentation @@ -41,7 +40,8 @@ public enum MariaDbVersion implements Version { Feature.selectForUpdateSkipLocked, // https://mariadb.com/kb/en/join-syntax/ - Feature.join, Feature.joinSimple, Feature.joinRight, Feature.joinNatural, Feature.joinLeft, + Feature.join, Feature.joinSimple, Feature.joinRight, Feature.joinNatural, + Feature.joinLeft, Feature.joinCross, Feature.joinOuter, Feature.joinInner, Feature.joinStraight, Feature.joinUsingColumns, @@ -64,8 +64,10 @@ public enum MariaDbVersion implements Version { // https://mariadb.com/kb/en/insert/ Feature.insert, Feature.insertValues, Feature.values, - Feature.insertFromSelect, Feature.insertModifierPriority, Feature.insertModifierIgnore, - Feature.insertUseSet, Feature.insertUseDuplicateKeyUpdate, Feature.insertReturningExpressionList, + Feature.insertFromSelect, Feature.insertModifierPriority, + Feature.insertModifierIgnore, + Feature.insertUseSet, Feature.insertUseDuplicateKeyUpdate, + Feature.insertReturningExpressionList, // https://mariadb.com/kb/en/update/ Feature.update, @@ -96,7 +98,8 @@ public enum MariaDbVersion implements Version { Feature.dropView, // https://mariadb.com/kb/en/drop-sequence/ Feature.dropSequence, Feature.dropTableIfExists, Feature.dropIndexIfExists, - Feature.dropViewIfExists, Feature.dropSchemaIfExists, Feature.dropSequenceIfExists, + Feature.dropViewIfExists, Feature.dropSchemaIfExists, + Feature.dropSequenceIfExists, // https://mariadb.com/kb/en/replace/ Feature.upsert, @@ -110,9 +113,11 @@ public enum MariaDbVersion implements Version { // https://mariadb.com/kb/en/create-view/ Feature.createView, Feature.createOrReplaceView, + Feature.createViewWithComment, // https://mariadb.com/kb/en/create-table/ - Feature.createTable, Feature.createTableCreateOptionStrings, Feature.createTableTableOptionStrings, + Feature.createTable, Feature.createTableCreateOptionStrings, + Feature.createTableTableOptionStrings, Feature.createTableFromSelect, Feature.createTableIfNotExists, // https://mariadb.com/kb/en/create-index/ Feature.createIndex, @@ -143,7 +148,7 @@ public enum MariaDbVersion implements Version { Feature.commit, // https://mariadb.com/kb/en/optimizer-hints/ Feature.mySqlHintStraightJoin, - Feature.mysqlCalcFoundRows, + Feature.mysqlCalcFoundRows, Feature.mysqlSqlCacheFlag)), ORACLE_MODE("oracle_mode", V10_5_4.copy().add(Feature.selectUnique).getFeatures()); diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java index 01bbce4c1..a7aeeaae0 100644 --- a/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java +++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java @@ -9,11 +9,10 @@ */ package net.sf.jsqlparser.util.validation.feature; -import net.sf.jsqlparser.parser.feature.Feature; - import java.util.Collections; import java.util.EnumSet; import java.util.Set; +import net.sf.jsqlparser.parser.feature.Feature; /** * Please add Features supported and place a link to public documentation @@ -33,11 +32,13 @@ public enum MySqlVersion implements Version { // https://dev.mysql.com/doc/refman/8.0/en/select.html Feature.select, Feature.selectGroupBy, Feature.selectHaving, - Feature.limit, Feature.limitOffset, Feature.offset, Feature.offsetParam, Feature.orderBy, + Feature.limit, Feature.limitOffset, Feature.offset, Feature.offsetParam, + Feature.orderBy, Feature.selectForUpdate, Feature.selectForUpdateOfTable, Feature.selectForUpdateNoWait, Feature.selectForUpdateSkipLocked, + Feature.selectForShare, Feature.distinct, Feature.setOperation, @@ -51,7 +52,8 @@ public enum MySqlVersion implements Version { Feature.function, // https://dev.mysql.com/doc/refman/8.0/en/join.html - Feature.join, Feature.joinSimple, Feature.joinLeft, Feature.joinRight, Feature.joinOuter, + Feature.join, Feature.joinSimple, Feature.joinLeft, Feature.joinRight, + Feature.joinOuter, Feature.joinNatural, Feature.joinInner, Feature.joinCross, Feature.joinStraight, Feature.joinUsingColumns, @@ -59,6 +61,7 @@ public enum MySqlVersion implements Version { Feature.insert, Feature.insertValues, Feature.values, + Feature.tableStatement, Feature.insertFromSelect, Feature.insertUseSet, Feature.insertModifierPriority, Feature.insertModifierIgnore, Feature.insertUseDuplicateKeyUpdate, @@ -99,9 +102,11 @@ public enum MySqlVersion implements Version { Feature.createSchema, // https://dev.mysql.com/doc/refman/8.0/en/create-view.html Feature.createView, + Feature.createViewWithComment, Feature.createOrReplaceView, // https://dev.mysql.com/doc/refman/8.0/en/create-table.html - Feature.createTable, Feature.createTableCreateOptionStrings, Feature.createTableTableOptionStrings, + Feature.createTable, Feature.createTableCreateOptionStrings, + Feature.createTableTableOptionStrings, Feature.createTableFromSelect, Feature.createTableIfNotExists, // https://dev.mysql.com/doc/refman/8.0/en/create-index.html Feature.createIndex, @@ -110,6 +115,7 @@ public enum MySqlVersion implements Version { // https://dev.mysql.com/doc/refman/8.0/en/describe.html Feature.describe, + Feature.desc, // https://dev.mysql.com/doc/refman/8.0/en/explain.html Feature.explain, // https://dev.mysql.com/doc/refman/8.0/en/show.html diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/PostgresqlVersion.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/PostgresqlVersion.java index c5d3d898a..08bf3bf1a 100644 --- a/src/main/java/net/sf/jsqlparser/util/validation/feature/PostgresqlVersion.java +++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/PostgresqlVersion.java @@ -12,7 +12,6 @@ import java.util.Collections; import java.util.EnumSet; import java.util.Set; - import net.sf.jsqlparser.parser.feature.Feature; /** @@ -33,7 +32,8 @@ public enum PostgresqlVersion implements Version { Feature.exprSimilarTo, // https://www.postgresql.org/docs/current/sql-select.html Feature.select, - Feature.selectGroupBy, Feature.function, Feature.tableFunction, Feature.lateralSubSelect, + Feature.selectGroupBy, Feature.function, Feature.tableFunction, + Feature.lateralSubSelect, Feature.selectHaving, // https://www.postgresql.org/docs/current/queries-table-expressions.html#QUERIES-GROUPING-SETS Feature.selectGroupByGroupingSets, @@ -73,6 +73,9 @@ public enum PostgresqlVersion implements Version { Feature.orderBy, Feature.orderByNullOrdering, + Feature.selectForNoKeyUpdate, + Feature.selectForKeyShare, + Feature.selectForShare, Feature.selectForUpdate, Feature.selectForUpdateOfTable, Feature.selectForUpdateNoWait, @@ -107,6 +110,11 @@ public enum PostgresqlVersion implements Version { // https://www.postgresql.org/docs/current/sql-alterview.html // Feature.alterView, + // https://www.postgresql.org/docs/16/sql-refreshmaterializedview.html + Feature.refreshMaterializedView, + Feature.refreshMaterializedWithNoDataView, + Feature.refreshMaterializedWithDataView, + // https://www.postgresql.org/docs/current/sql-insert.html Feature.insert, Feature.insertValues, @@ -151,12 +159,9 @@ public enum PostgresqlVersion implements Version { // https://www.postgresql.org/docs/current/sql-reset.html Feature.reset, // https://www.postgresql.org/docs/current/sql-commit.html - Feature.commit - )), - V11("11", V10.copy().getFeatures()), - V12("12", V11.copy().getFeatures()), - V13("13", V12.copy().getFeatures()), - V14("14", V13.copy().getFeatures()); + Feature.commit)), V11("11", V10.copy().getFeatures()), V12("12", + V11.copy().getFeatures()), V13("13", + V12.copy().getFeatures()), V14("14", V13.copy().getFeatures()); private Set features; private String versionString; @@ -176,7 +181,8 @@ public enum PostgresqlVersion implements Version { * @param unsupported * @see #copy() to copy from previous version */ - PostgresqlVersion(String versionString, Set featuresSupported, Set unsupported) { + PostgresqlVersion(String versionString, Set featuresSupported, + Set unsupported) { this.versionString = versionString; this.features = featuresSupported; this.features.removeAll(unsupported); diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/CreateViewValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/CreateViewValidator.java index 2723cfc25..e2910ada3 100644 --- a/src/main/java/net/sf/jsqlparser/util/validation/validator/CreateViewValidator.java +++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/CreateViewValidator.java @@ -33,6 +33,8 @@ public void validate(CreateView createView) { Feature.createViewTemporary); validateFeature(c, createView.isMaterialized(), Feature.createViewMaterialized); validateName(c, NamedObject.view, createView.getView().getFullyQualifiedName(), false); + validateFeature(c, createView.getViewCommentOptions() != null, + Feature.createViewWithComment); } SelectValidator v = getValidator(SelectValidator.class); Select select = createView.getSelect(); diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java index fcc554dd6..a0794b831 100644 --- a/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java +++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java @@ -79,6 +79,9 @@ import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.conditional.XorExpression; import net.sf.jsqlparser.expression.operators.relational.Between; +import net.sf.jsqlparser.expression.operators.relational.ContainedBy; +import net.sf.jsqlparser.expression.operators.relational.Contains; +import net.sf.jsqlparser.expression.operators.relational.DoubleAnd; import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; @@ -101,6 +104,8 @@ import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator; import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression; import net.sf.jsqlparser.expression.operators.relational.SupportsOldOracleJoinSyntax; +import net.sf.jsqlparser.expression.operators.relational.TSQLLeftJoin; +import net.sf.jsqlparser.expression.operators.relational.TSQLRightJoin; import net.sf.jsqlparser.parser.feature.Feature; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.select.AllColumns; @@ -290,6 +295,21 @@ public void visit(NotEqualsTo notEqualsTo) { " " + notEqualsTo.getStringExpression() + " "); } + @Override + public void visit(DoubleAnd doubleAnd) { + + } + + @Override + public void visit(Contains contains) { + + } + + @Override + public void visit(ContainedBy containedBy) { + + } + @Override public void visit(NullValue nullValue) { // nothing to validate @@ -676,4 +696,16 @@ public void visit(RangeExpression rangeExpression) { rangeExpression.getStartExpression().accept(this); rangeExpression.getEndExpression().accept(this); } + + @Override + public void visit(TSQLLeftJoin tsqlLeftJoin) { + tsqlLeftJoin.getLeftExpression().accept(this); + tsqlLeftJoin.getRightExpression().accept(this); + } + + @Override + public void visit(TSQLRightJoin tsqlRightJoin) { + tsqlRightJoin.getLeftExpression().accept(this); + tsqlRightJoin.getRightExpression().accept(this); + } } diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/RefreshMaterializedViewStatementValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/RefreshMaterializedViewStatementValidator.java new file mode 100644 index 000000000..cca8785c2 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/RefreshMaterializedViewStatementValidator.java @@ -0,0 +1,39 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2019 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.util.validation.validator; + +import net.sf.jsqlparser.parser.feature.Feature; +import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement; +import net.sf.jsqlparser.util.validation.ValidationCapability; +import net.sf.jsqlparser.util.validation.metadata.NamedObject; + +/** + * @author jxnu-liguobin + */ + +public class RefreshMaterializedViewStatementValidator + extends AbstractValidator { + + @Override + public void validate(RefreshMaterializedViewStatement viewStatement) { + validateFeatureAndName(Feature.refreshMaterializedView, NamedObject.table, + viewStatement.getView().getName()); + for (ValidationCapability c : getCapabilities()) { + // default + validateFeature(c, viewStatement.getRefreshMode() == null, + Feature.refreshMaterializedView); + // specify WITH DATA + validateOptionalFeature(c, viewStatement.getRefreshMode(), + Feature.refreshMaterializedWithDataView); + validateOptionalFeature(c, viewStatement.getRefreshMode(), + Feature.refreshMaterializedWithNoDataView); + } + } +} diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java index 88166c1b5..97fcd08a3 100644 --- a/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java +++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java @@ -9,6 +9,7 @@ */ package net.sf.jsqlparser.util.validation.validator; +import java.util.List; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.MySQLIndexHint; import net.sf.jsqlparser.expression.SQLServerHints; @@ -16,6 +17,7 @@ import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.select.ExceptOp; import net.sf.jsqlparser.statement.select.Fetch; +import net.sf.jsqlparser.statement.select.ForMode; import net.sf.jsqlparser.statement.select.FromItemVisitor; import net.sf.jsqlparser.statement.select.IntersectOp; import net.sf.jsqlparser.statement.select.Join; @@ -33,6 +35,7 @@ import net.sf.jsqlparser.statement.select.SelectVisitor; import net.sf.jsqlparser.statement.select.SetOperationList; import net.sf.jsqlparser.statement.select.TableFunction; +import net.sf.jsqlparser.statement.select.TableStatement; import net.sf.jsqlparser.statement.select.UnPivot; import net.sf.jsqlparser.statement.select.UnionOp; import net.sf.jsqlparser.statement.select.Values; @@ -41,8 +44,6 @@ import net.sf.jsqlparser.util.validation.ValidationUtil; import net.sf.jsqlparser.util.validation.metadata.NamedObject; -import java.util.List; - /** * @author gitmotte */ @@ -85,8 +86,15 @@ public void visit(PlainSelect plainSelect) { isNotEmpty(plainSelect.getOrderByElements()) && plainSelect.isOracleSiblings(), Feature.oracleOrderBySiblings); - if (plainSelect.isForUpdate()) { + if (plainSelect.getForMode() != null) { validateFeature(c, Feature.selectForUpdate); + validateFeature(c, plainSelect.getForMode() == ForMode.KEY_SHARE, + Feature.selectForKeyShare); + validateFeature(c, plainSelect.getForMode() == ForMode.NO_KEY_UPDATE, + Feature.selectForNoKeyUpdate); + validateFeature(c, plainSelect.getForMode() == ForMode.SHARE, + Feature.selectForShare); + validateOptionalFeature(c, plainSelect.getForUpdateTable(), Feature.selectForUpdateOfTable); validateOptionalFeature(c, plainSelect.getWait(), Feature.selectForUpdateWait); @@ -306,6 +314,11 @@ public void visit(LateralSubSelect lateralSubSelect) { validateOptional(lateralSubSelect.getSelect(), e -> e.accept(this)); } + @Override + public void visit(TableStatement tableStatement) { + getValidator(TableStatementValidator.class).validate(tableStatement); + } + @Override public void visit(TableFunction tableFunction) { validateFeature(Feature.tableFunction); diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/StatementValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/StatementValidator.java index 4bc3744b7..ec9650105 100644 --- a/src/main/java/net/sf/jsqlparser/util/validation/validator/StatementValidator.java +++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/StatementValidator.java @@ -51,6 +51,7 @@ import net.sf.jsqlparser.statement.grant.Grant; import net.sf.jsqlparser.statement.insert.Insert; import net.sf.jsqlparser.statement.merge.Merge; +import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.show.ShowIndexStatement; import net.sf.jsqlparser.statement.show.ShowTablesStatement; @@ -85,6 +86,11 @@ public void visit(AlterView alterView) { getValidator(AlterViewValidator.class).validate(alterView); } + @Override + public void visit(RefreshMaterializedViewStatement materializedView) { + getValidator(RefreshMaterializedViewStatementValidator.class).validate(materializedView); + } + @Override public void visit(Delete delete) { getValidator(DeleteValidator.class).validate(delete); @@ -203,13 +209,16 @@ public void visit(Comment comment) { @Override public void visit(DescribeStatement describe) { validateFeature(Feature.describe); + validateFeature(Feature.desc); validateOptionalFromItem(describe.getTable()); } @Override public void visit(ExplainStatement explain) { validateFeature(Feature.explain); - explain.getStatement().accept(this); + if (explain.getStatement() != null) { + explain.getStatement().accept(this); + } } diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidator.java new file mode 100644 index 000000000..4b954126e --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidator.java @@ -0,0 +1,27 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2019 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.util.validation.validator; + +import net.sf.jsqlparser.parser.feature.Feature; +import net.sf.jsqlparser.statement.select.TableStatement; +import net.sf.jsqlparser.util.validation.ValidationCapability; + +/** + * @author jxnu-liguobin + */ +public class TableStatementValidator extends AbstractValidator { + + @Override + public void validate(TableStatement statement) { + for (ValidationCapability c : getCapabilities()) { + validateFeature(c, Feature.tableStatement); + } + } +} diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index f0dfae767..3144b3103 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -59,6 +59,7 @@ import net.sf.jsqlparser.statement.drop.*; import net.sf.jsqlparser.statement.insert.*; import net.sf.jsqlparser.statement.execute.*; import net.sf.jsqlparser.statement.select.*; +import net.sf.jsqlparser.statement.refresh.*; import net.sf.jsqlparser.statement.show.*; import net.sf.jsqlparser.statement.truncate.*; import net.sf.jsqlparser.statement.update.*; @@ -138,7 +139,6 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | -| | | | @@ -182,8 +182,9 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | -| +| | +| | | | @@ -191,6 +192,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | +| | | | @@ -251,6 +253,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | +| | | | @@ -271,6 +274,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | +| | | | @@ -293,6 +297,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | +| | | | @@ -364,6 +369,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | +| | | | @@ -373,9 +379,11 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | +| | | | +| | | | @@ -393,6 +401,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | +| | | | @@ -413,8 +422,8 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | -| @@ -451,6 +460,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | +| | | | @@ -476,16 +486,19 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ TOKEN : /* Statement Separators */ { - + } TOKEN : /* Operators */ { " ()* "="> -| )* "="> -| )* ">"> -| )* "="> -| )* "|"> +| )* "="> +| )* ">"> +| )* "="> +| )* "|"> +| +| "> +| } TOKEN : /* Date/Time with time zones */ @@ -600,7 +613,7 @@ TOKEN: Statement Statement() #Statement: -{ +{ IfElseStatement ifElseStatement = null; Statement stm = null; Statement stm2 = null; @@ -609,10 +622,10 @@ Statement Statement() #Statement: { try { ( - condition=Condition() + condition=Condition() ( stm = SingleStatement() | stm = Block() ) { ifElseStatement = new IfElseStatement(condition, stm); } [ { ifElseStatement.setUsingSemicolonForIfStatement(true); } ] - [ LOOKAHEAD(2) + [ LOOKAHEAD(2) ( stm2 = SingleStatement() | stm2 = Block() ) { ifElseStatement.setElseStatement(stm2); } [ { ifElseStatement.setUsingSemicolonForElseStatement(true); }] ] @@ -641,7 +654,7 @@ Statement Statement() #Statement: } Statement SingleStatement() : -{ +{ Statement stm = null; List with = null; } @@ -665,6 +678,8 @@ Statement SingleStatement() : | stm = Select() | + stm = TableStatement() + | LOOKAHEAD(3) stm = Upsert() | LOOKAHEAD(2) stm = Alter() @@ -688,6 +703,8 @@ Statement SingleStatement() : | stm = Show() | + stm = RefreshMaterializedView() + | stm = Use() | stm = SavepointStatement() @@ -752,7 +769,7 @@ Block Block() #Block : { error_skipto(ST_SEMICOLON); } else { throw e; - } + } } { @@ -778,9 +795,9 @@ Statements Statements() #Statements: { try { ( ( - condition=Condition() + condition=Condition() ( stm = SingleStatement() | stm = Block() ) { ifElseStatement = new IfElseStatement(condition, stm); } - [ LOOKAHEAD(2) + [ LOOKAHEAD(2) [ { ifElseStatement.setUsingSemicolonForIfStatement(true); } ] ( stm2 = SingleStatement() | stm2 = Block() ) { ifElseStatement.setElseStatement(stm2); } ] @@ -789,7 +806,7 @@ Statements Statements() #Statements: { ) | ( - stm = SingleStatement() + stm = SingleStatement() | stm = Block() [ LOOKAHEAD(2) ] @@ -863,14 +880,15 @@ DeclareStatement Declare(): { } { userVariable = UserVariable() ( - ( "(" colDef = ColumnDefinition() - { - stmt.withUserVariable(userVariable) - .withDeclareType(DeclareType.TABLE) - .addColumnDefinition(colDef); - } - ("," colDef = ColumnDefinition() { stmt.addColumnDefinition(colDef); })* ")" - ) + LOOKAHEAD(2) ( + "(" colDef = ColumnDefinition() + { + stmt.withUserVariable(userVariable) + .withDeclareType(DeclareType.TABLE) + .addColumnDefinition(colDef); + } + ("," colDef = ColumnDefinition() { stmt.addColumnDefinition(colDef); })* ")" + ) | typeName = RelObjectName() { @@ -974,11 +992,11 @@ RenameTableStatement RenameTableStatement(): { Token token; } { - + [ LOOKAHEAD(2) { usingTableKeyword = true; } ] [ LOOKAHEAD(2) { usesIfExistsKeyword = true; } ] oldName = Table() - [ ( + [ ( token= { waitDirective = "WAIT " + token.image; } | { waitDirective = "NOWAIT"; } @@ -986,8 +1004,8 @@ RenameTableStatement RenameTableStatement(): { newName = Table() - { - renameTableStatement = new RenameTableStatement(oldName, newName, usingTableKeyword, usesIfExistsKeyword, waitDirective); + { + renameTableStatement = new RenameTableStatement(oldName, newName, usingTableKeyword, usesIfExistsKeyword, waitDirective); } ( @@ -1000,7 +1018,7 @@ RenameTableStatement RenameTableStatement(): { } )* - { + { return renameTableStatement; } } @@ -1013,21 +1031,21 @@ PurgeStatement PurgeStatement(): { Token userToken = null; } { - + ( table=Table() { purgeStatement = new PurgeStatement(table); } - | + | index=Index() { purgeStatement = new PurgeStatement(index); } | { purgeStatement = new PurgeStatement(PurgeObjectType.RECYCLEBIN); } | { purgeStatement = new PurgeStatement(PurgeObjectType.DBA_RECYCLEBIN); } | - tableSpaceToken= [ userToken= ] { + tableSpaceToken= [ userToken= ] { purgeStatement = new PurgeStatement( PurgeObjectType.TABLESPACE , tableSpaceToken.image - , userToken!=null ? userToken.image : null); + , userToken!=null ? userToken.image : null); } ) @@ -1038,29 +1056,43 @@ PurgeStatement PurgeStatement(): { DescribeStatement Describe(): { Table table; + DescribeStatement stmt = new DescribeStatement(); + Token tk = null; } { - table = Table() + (tk= | tk=) + table = Table() { stmt.setDescribeType(tk.image).setTable(table); } { - return new DescribeStatement(table); + return stmt; } } ExplainStatement Explain(): { Select select; + Table table = null; List options = null; + ExplainStatement es = new ExplainStatement(); } { - options=ExplainStatementOptions() - select = Select( ) - { - ExplainStatement es = new ExplainStatement(select); - if(options != null && !options.isEmpty()) { - for(ExplainStatement.Option o : options) { - es.addOption(o); - } - } - return es; - } + ( + LOOKAHEAD(3)( + options=ExplainStatementOptions() + select = Select( ) + { + es.setStatement(select); + if (options != null && !options.isEmpty()) { + for(ExplainStatement.Option o : options) { + es.addOption(o); + } + } + } + ) + | + ( + table=Table( ) { es.setTable(table); } + ) + + ) + { return es; } } /** @@ -1210,6 +1242,32 @@ ShowIndexStatement ShowIndex(): { } } +Statement RefreshMaterializedView(): { + Table view = null; + boolean concurrently = false; + RefreshMode refreshMode = null; + List captureRest; +} +{ + + [ LOOKAHEAD(2) { concurrently = true; } ] + view = Table() + [ + { refreshMode = RefreshMode.WITH_DATA; } + [ + { refreshMode = RefreshMode.WITH_NO_DATA; } + ] + + ] + captureRest = captureRest() + { + if (concurrently && refreshMode == RefreshMode.WITH_NO_DATA) { + return new UnsupportedStatement("REFRESH", captureRest); + } else { + return new RefreshMaterializedViewStatement(view, concurrently, refreshMode); + } + } +} // https://dev.mysql.com/doc/refman/8.0/en/show-tables.html ShowTablesStatement ShowTables(): { ShowTablesStatement showTablesStatement; @@ -1261,7 +1319,7 @@ ReturningClause ReturningClause(): List dataItems = null; } { - ( keyword= | keyword="RETURN" ) + ( keyword= | keyword= ) selectItems = SelectItemsList() [ @@ -1304,7 +1362,7 @@ Update Update( List with ): { update.setOracleHint(getOracleHint()); } [ LOOKAHEAD(2) { modifierPriority = UpdateModifierPriority.LOW_PRIORITY; }] [ LOOKAHEAD(2) { modifierIgnore = true; }] - table=TableWithAlias() [ startJoins=JoinsList() ] + table=TableWithAliasAndMysqlIndexHint() [ startJoins=JoinsList() ] updateSets = UpdateSets() { update.setUpdateSets(updateSets); } [ outputClause = OutputClause() {update.setOutputClause(outputClause); } ] @@ -1645,11 +1703,12 @@ Statement Merge( List with ) : { Expression condition; MergeUpdate update; MergeInsert insert; + OutputClause outputClause; } { { merge.setOracleHint(getOracleHint()); } table=TableWithAlias() { merge.setTable(table); } fromItem = FromItem() { merge.setFromItem(fromItem); } - "(" condition = Expression() { merge.setOnCondition(condition); } ")" + condition = Expression() { merge.setOnCondition(condition); } [ ( LOOKAHEAD(2) update = MergeUpdateClause() { merge.setMergeUpdate(update); } @@ -1659,18 +1718,23 @@ Statement Merge( List with ) : { ) ] + [ outputClause = OutputClause() { merge.setOutputClause(outputClause); } ] + { return merge.withWithItemsList(with); } } MergeUpdate MergeUpdateClause() : { - MergeUpdate mu; + MergeUpdate mu = new MergeUpdate(); List updateSets; + Expression predicate; Expression condition; } { - + + [ predicate = Expression() { mu.setAndPredicate(predicate); } ] + - updateSets = UpdateSets() { mu = new MergeUpdate(updateSets); } + updateSets = UpdateSets() { mu.setUpdateSets(updateSets); } [ condition = Expression() { mu.setWhereCondition(condition); }] [ condition = Expression() { mu.setDeleteWhereCondition(condition); } ] @@ -1680,12 +1744,15 @@ MergeUpdate MergeUpdateClause() : { MergeInsert MergeInsertClause() : { MergeInsert mi = new MergeInsert(); + Expression predicate; ExpressionList columns; ExpressionList expList; Expression condition; } { - + + [ predicate = Expression() { mi.setAndPredicate(predicate); } ] + [ "(" columns = ColumnList() ")" { @@ -1718,16 +1785,18 @@ Column Column() #Column : { List data = new ArrayList(); ArrayConstructor arrayConstructor = null; + Token tk = null; } { data = RelObjectNameList() - + [ LOOKAHEAD(2) tk= ] // @todo: we better should return a SEQUENCE instead of a COLUMN [ "." { data.add("nextval"); } ] [ LOOKAHEAD(2) arrayConstructor = ArrayConstructor(false) ] { Column col = new Column(data); + if (tk != null) { col.withCommentText(tk.image); } if (arrayConstructor!=null) { col.setArrayConstructor(arrayConstructor); } @@ -1748,7 +1817,7 @@ String RelObjectNameWithoutValue() : { Token tk = null; } { ( tk= | tk= | tk= | tk= | tk= | tk= | tk= - | tk="ACTION" | tk="ACTIVE" | tk="ADD" | tk="ADVANCE" | tk="ADVISE" | tk="AGAINST" | tk="ALGORITHM" | tk="ALTER" | tk="ANALYZE" | tk="APPLY" | tk="ARCHIVE" | tk="ARRAY" | tk="ASC" | tk="AT" | tk="AUTHORIZATION" | tk="AUTO" | tk="BEGIN" | tk="BERNOULLI" | tk="BINARY" | tk="BIT" | tk="BLOCK" | tk="BROWSE" | tk="BUFFERS" | tk="BY" | tk="BYTE" | tk="BYTES" | tk="CACHE" | tk="CALL" | tk="CASCADE" | tk="CASE" | tk="CAST" | tk="CHANGE" | tk="CHANGES" | tk="CHAR" | tk="CHARACTER" | tk="CHECKPOINT" | tk="CLOSE" | tk="COLLATE" | tk="COLUMN" | tk="COLUMNS" | tk="COMMENT" | tk="COMMIT" | tk="CONFLICT" | tk="CONVERT" | tk="COSTS" | tk="CS" | tk="CYCLE" | tk="DATABASE" | tk="DDL" | tk="DECLARE" | tk="DEFAULT" | tk="DEFERRABLE" | tk="DELAYED" | tk="DELETE" | tk="DESC" | tk="DESCRIBE" | tk="DISABLE" | tk="DISCONNECT" | tk="DIV" | tk="DML" | tk="DO" | tk="DOMAIN" | tk="DROP" | tk="DUMP" | tk="DUPLICATE" | tk="ELEMENTS" | tk="EMIT" | tk="ENABLE" | tk="END" | tk="ESCAPE" | tk="EXCLUDE" | tk="EXEC" | tk="EXECUTE" | tk="EXPLAIN" | tk="EXPLICIT" | tk="EXTENDED" | tk="EXTRACT" | tk="FALSE" | tk="FILTER" | tk="FIRST" | tk="FLUSH" | tk="FN" | tk="FOLLOWING" | tk="FORMAT" | tk="FULLTEXT" | tk="FUNCTION" | tk="GLOBAL" | tk="GRANT" | tk="GUARD" | tk="HISTORY" | tk="HOPPING" | tk="INCLUDE" | tk="INCREMENT" | tk="INDEX" | tk="INSERT" | tk="INTERLEAVE" | tk="INTERPRET" | tk="ISNULL" | tk="JSON" | tk="KEEP" | tk="KEY" | tk="KEYS" | tk="LAST" | tk="LEADING" | tk="LINK" | tk="LOCAL" | tk="LOCKED" | tk="LOG" | tk="MATCH" | tk="MATCHED" | tk="MATERIALIZED" | tk="MAXVALUE" | tk="MEMBER" | tk="MERGE" | tk="MINVALUE" | tk="MODIFY" | tk="MOVEMENT" | tk="NEXT" | tk="NO" | tk="NOCACHE" | tk="NOKEEP" | tk="NOLOCK" | tk="NOMAXVALUE" | tk="NOMINVALUE" | tk="NOORDER" | tk="NOTHING" | tk="NOTNULL" | tk="NOVALIDATE" | tk="NOWAIT" | tk="NULLS" | tk="OF" | tk="OFF" | tk="OPEN" | tk="OVER" | tk="OVERLAPS" | tk="PARALLEL" | tk="PARENT" | tk="PARTITION" | tk="PATH" | tk="PERCENT" | tk="PLACING" | tk="PRECEDING" | tk="PRECISION" | tk="PRIMARY" | tk="PRIOR" | tk="PURGE" | tk="QUERY" | tk="QUICK" | tk="QUIESCE" | tk="RANGE" | tk="RAW" | tk="READ" | tk="RECYCLEBIN" | tk="REFERENCES" | tk="REFRESH" | tk="REGISTER" | tk="RENAME" | tk="REPEATABLE" | tk="REPLACE" | tk="RESET" | tk="RESTART" | tk="RESTRICT" | tk="RESTRICTED" | tk="RESUMABLE" | tk="RESUME" | tk="RLIKE" | tk="ROLLBACK" | tk="ROOT" | tk="ROW" | tk="ROWS" | tk="RR" | tk="RS" | tk="SAVEPOINT" | tk="SCHEMA" | tk="SEED" | tk="SEPARATOR" | tk="SEQUENCE" | tk="SESSION" | tk="SETS" | tk="SHOW" | tk="SHUTDOWN" | tk="SIBLINGS" | tk="SIGNED" | tk="SIMILAR" | tk="SIZE" | tk="SKIP" | tk="STORED" | tk="STRING" | tk="SUSPEND" | tk="SWITCH" | tk="SYNONYM" | tk="SYSTEM" | tk="TABLE" | tk="TABLESPACE" | tk="TEMP" | tk="TEMPORARY" | tk="THEN" | tk="TIMEOUT" | tk="TIMESTAMPTZ" | tk="TO" | tk="TRIGGER" | tk="TRUE" | tk="TRUNCATE" | tk="TUMBLING" | tk="TYPE" | tk="UNLOGGED" | tk="UNQIESCE" | tk="UNSIGNED" | tk="UPDATE" | tk="UPSERT" | tk="UR" | tk="USER" | tk="VALIDATE" | tk="VERBOSE" | tk="VIEW" | tk="WAIT" | tk="WITHIN" | tk="WITHOUT" | tk="WORK" | tk="XML" | tk="XMLAGG" | tk="XMLDATA" | tk="XMLSCHEMA" | tk="XMLTEXT" | tk="XSINIL" | tk="YAML" | tk="YES" | tk="ZONE" ) + | tk="ACTION" | tk="ACTIVE" | tk="ADD" | tk="ADVANCE" | tk="ADVISE" | tk="AGAINST" | tk="ALGORITHM" | tk="ALTER" | tk="ANALYZE" | tk="APPLY" | tk="ARCHIVE" | tk="ARRAY" | tk="ASC" | tk="AT" | tk="AUTHORIZATION" | tk="AUTO" | tk="BEGIN" | tk="BERNOULLI" | tk="BINARY" | tk="BIT" | tk="BLOCK" | tk="BROWSE" | tk="BUFFERS" | tk="BY" | tk="BYTE" | tk="BYTES" | tk="CACHE" | tk="CALL" | tk="CASCADE" | tk="CASE" | tk="CAST" | tk="CHANGE" | tk="CHANGES" | tk="CHAR" | tk="CHARACTER" | tk="CHECKPOINT" | tk="CLOSE" | tk="COLLATE" | tk="COLUMN" | tk="COLUMNS" | tk="COMMENT" | tk="COMMIT" | tk="CONCURRENTLY" | tk="CONFLICT" | tk="CONSTRAINTS" | tk="CONVERT" | tk="COSTS" | tk="CS" | tk="CYCLE" | tk="DATA" | tk="DATABASE" | tk="DDL" | tk="DECLARE" | tk="DEFAULT" | tk="DEFERRABLE" | tk="DELAYED" | tk="DELETE" | tk="DESC" | tk="DESCRIBE" | tk="DISABLE" | tk="DISCONNECT" | tk="DIV" | tk="DML" | tk="DO" | tk="DOMAIN" | tk="DROP" | tk="DUMP" | tk="DUPLICATE" | tk="ELEMENTS" | tk="EMIT" | tk="ENABLE" | tk="END" | tk="ESCAPE" | tk="EXCLUDE" | tk="EXEC" | tk="EXECUTE" | tk="EXPLAIN" | tk="EXPLICIT" | tk="EXTENDED" | tk="EXTRACT" | tk="FALSE" | tk="FILTER" | tk="FIRST" | tk="FLUSH" | tk="FN" | tk="FOLLOWING" | tk="FORMAT" | tk="FULLTEXT" | tk="FUNCTION" | tk="GRANT" | tk="GUARD" | tk="HASH" | tk="HISTORY" | tk="HOPPING" | tk="INCLUDE" | tk="INCREMENT" | tk="INDEX" | tk="INSERT" | tk="INTERLEAVE" | tk="INTERPRET" | tk="INVALIDATE" | tk="ISNULL" | tk="JSON" | tk="KEEP" | tk="KEY" | tk="KEYS" | tk="LAST" | tk="LEADING" | tk="LINK" | tk="LOCAL" | tk="LOCKED" | tk="LOG" | tk="LOOP" | tk="MATCH" | tk="MATCHED" | tk="MATERIALIZED" | tk="MAXVALUE" | tk="MEMBER" | tk="MERGE" | tk="MINVALUE" | tk="MODIFY" | tk="MOVEMENT" | tk="NEXT" | tk="NO" | tk="NOCACHE" | tk="NOKEEP" | tk="NOLOCK" | tk="NOMAXVALUE" | tk="NOMINVALUE" | tk="NOORDER" | tk="NOTHING" | tk="NOTNULL" | tk="NOVALIDATE" | tk="NOWAIT" | tk="NULLS" | tk="OF" | tk="OFF" | tk="OPEN" | tk="OVER" | tk="OVERLAPS" | tk="PARALLEL" | tk="PARENT" | tk="PARTITION" | tk="PATH" | tk="PERCENT" | tk="PLACING" | tk="PRECEDING" | tk="PRECISION" | tk="PRIMARY" | tk="PRIOR" | tk="PURGE" | tk="QUERY" | tk="QUICK" | tk="QUIESCE" | tk="RANGE" | tk="RAW" | tk="READ" | tk="RECYCLEBIN" | tk="REFERENCES" | tk="REFRESH" | tk="REGISTER" | tk="REMOTE" | tk="RENAME" | tk="REPEATABLE" | tk="REPLACE" | tk="RESET" | tk="RESTART" | tk="RESTRICT" | tk="RESTRICTED" | tk="RESUMABLE" | tk="RESUME" | tk="RETURN" | tk="RLIKE" | tk="ROLLBACK" | tk="ROLLUP" | tk="ROOT" | tk="ROW" | tk="ROWS" | tk="RR" | tk="RS" | tk="SAVEPOINT" | tk="SCHEMA" | tk="SEED" | tk="SEPARATOR" | tk="SEQUENCE" | tk="SESSION" | tk="SETS" | tk="SHARE" | tk="SHOW" | tk="SHUTDOWN" | tk="SIBLINGS" | tk="SIGNED" | tk="SIMILAR" | tk="SIZE" | tk="SKIP" | tk="STORED" | tk="STRING" | tk="SUSPEND" | tk="SWITCH" | tk="SYNONYM" | tk="SYSTEM" | tk="TABLE" | tk="TABLESPACE" | tk="TEMP" | tk="TEMPORARY" | tk="THEN" | tk="TIMEOUT" | tk="TIMESTAMPTZ" | tk="TO" | tk="TRIGGER" | tk="TRUE" | tk="TRUNCATE" | tk="TUMBLING" | tk="TYPE" | tk="UNLOGGED" | tk="UNQIESCE" | tk="UNSIGNED" | tk="UPDATE" | tk="UPSERT" | tk="UR" | tk="USER" | tk="VALIDATE" | tk="VERBOSE" | tk="VIEW" | tk="WAIT" | tk="WITHIN" | tk="WITHOUT" | tk="WORK" | tk="XML" | tk="XMLAGG" | tk="XMLDATA" | tk="XMLSCHEMA" | tk="XMLTEXT" | tk="XSINIL" | tk="YAML" | tk="YES" | tk="ZONE" ) { return tk.image; } } @@ -1792,7 +1861,10 @@ String RelObjectNameExt(): ( result=RelObjectName() | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= - | tk= | tk= | tk= | tk= ) + | tk= | tk= | tk= | tk= + | tk= + | tk= + ) { return tk!=null ? tk.image : result; } } @@ -1838,6 +1910,19 @@ Table TableWithAlias(): { return table; } } +Table TableWithAliasAndMysqlIndexHint(): +{ + Table table = null; + Alias alias = null; + MySQLIndexHint indexHint = null; +} +{ + table=Table() + [ LOOKAHEAD(2) alias=Alias() { table.setAlias(alias); } ] + [ LOOKAHEAD(2) indexHint=MySQLIndexHint() { table.setHint(indexHint); } ] + { return table; } +} + Number Number(): { Token token; @@ -1935,6 +2020,24 @@ Select Select() #Select: } } +TableStatement TableStatement(): +{ + Table table = null; + List orderByElements = null; + Limit limit = null; + Offset offset = null; + TableStatement tableStatement = new TableStatement(); +}{ + + table = Table() + { tableStatement.setTable(table); } + [ LOOKAHEAD( ) orderByElements = OrderByElements() { tableStatement.setOrderByElements(orderByElements); } ] + [ LOOKAHEAD() limit=LimitWithOffset() { tableStatement.setLimit(limit);} ] + [ LOOKAHEAD() offset = Offset() { tableStatement.setOffset(offset);} ] + { return tableStatement; } + /* Support operationList */ +} + ParenthesedSelect ParenthesedSelect() #ParenthesedSelect: { ParenthesedSelect parenthesedSelect = new ParenthesedSelect(); @@ -2181,13 +2284,19 @@ PlainSelect PlainSelect() #PlainSelect: [ LOOKAHEAD(, { limit==null }) limit = LimitWithOffset() { plainSelect.setLimit(limit); } ] [ LOOKAHEAD() fetch = Fetch() { plainSelect.setFetch(fetch); } ] [ LOOKAHEAD( ) withIsolation = WithIsolation() { plainSelect.setIsolation(withIsolation); } ] - [ LOOKAHEAD(2) { plainSelect.setForUpdate(true); } + [ LOOKAHEAD(2) + + ( + { plainSelect.setForMode(ForMode.UPDATE); } + | { plainSelect.setForMode(ForMode.SHARE); } + | ( { plainSelect.setForMode(ForMode.NO_KEY_UPDATE); }) + | ( { plainSelect.setForMode(ForMode.KEY_SHARE); }) + ) [ LOOKAHEAD(2) updateTable = Table() { plainSelect.setForUpdateTable(updateTable); } ] [ LOOKAHEAD() wait = Wait() { plainSelect.setWait(wait); } ] [ LOOKAHEAD(2) ( { plainSelect.setNoWait(true); } | { plainSelect.setSkipLocked(true); }) ] ] - [ LOOKAHEAD() optimize = OptimizeFor() { plainSelect.setOptimizeFor(optimize); } ] { plainSelect.setSelectItems(selectItems); @@ -2684,6 +2793,24 @@ List JoinsList(): } } +JoinHint JoinHint(): +{ + Token token; +} +{ + ( + token = + | + token = + | + token = + | + token = + ) + { + return new JoinHint(token.image); + } +} Join JoinerExpression() #JoinerExpression: { @@ -2693,7 +2820,7 @@ Join JoinerExpression() #JoinerExpression: Column tableColumn; List columns = null; KSQLJoinWindow joinWindow = null; - + JoinHint joinHint = null; } { [ { join.setGlobal(true); } ] @@ -2718,7 +2845,7 @@ Join JoinerExpression() #JoinerExpression: ] ( - + ( [ joinHint=JoinHint() {join.setJoinHint(joinHint); } ] ) | "," { join.setSimple(true); } ( { join.setOuter(true); } )? | @@ -2872,20 +2999,23 @@ GroupByElement GroupByColumnReferences(): ( LOOKAHEAD(2) ( - "(" - list = GroupingSet() { groupBy.addGroupingSet(list); } - ( LOOKAHEAD(2) "," list = GroupingSet() { groupBy.addGroupingSet(list); })* + + "(" + list = GroupingSet() { groupBy.addGroupingSet(list); } + ( LOOKAHEAD(2) "," list = GroupingSet() { groupBy.addGroupingSet(list); })* ")" ) | ( list = ExpressionList() { groupBy.setGroupByExpressions(list); } ( - LOOKAHEAD(2) "(" - list = GroupingSet() { groupBy.addGroupingSet(list); } - ( LOOKAHEAD(2) "," list = GroupingSet() { groupBy.addGroupingSet(list); })* + LOOKAHEAD(2) + "(" + list = GroupingSet() { groupBy.addGroupingSet(list); } + ( LOOKAHEAD(2) "," list = GroupingSet() { groupBy.addGroupingSet(list); })* ")" )? + [ LOOKAHEAD(2) { groupBy.setMysqlWithRollup(true); } ] ) ) { @@ -2960,6 +3090,7 @@ OrderByElement OrderByElement(): ) ] ] + [ LOOKAHEAD(2) { orderByElement.setMysqlWithRollup(true); } ] { orderByElement.setExpression(columnReference); return orderByElement; @@ -3075,13 +3206,44 @@ Fetch Fetch(): Fetch fetch = new Fetch(); Token token = null; Expression expression; + List fetchParameters = new ArrayList(); } { ( - // sqlserver-oracle-> FETCH (FIRST | NEXT) expression (ROW | ROWS) ONLY - ( { fetch.setFetchParamFirst(true); } | ) - expression = Expression() { fetch.setExpression(expression); } - ( { fetch.setFetchParam("ROWS"); } | ) + LOOKAHEAD(3) ( + ( { fetch.setFetchParamFirst(true); } | ) + ( + { fetch.addFetchParameter("ROWS"); } + | + { fetch.addFetchParameter("ROW"); } + ) + ( + { fetch.addFetchParameter("ONLY"); } + | + { fetch.addFetchParameter("WITH TIES"); } + ) + ) + | + ( + ( { fetch.setFetchParamFirst(true); } | ) + + // Expression is optional according to https://www.h2database.com/html/commands.html#select + expression = Expression() { fetch.setExpression(expression); } + [ { fetch.addFetchParameter("PERCENT"); } ] + ( + ( + { fetch.addFetchParameter("ROWS"); } + | + { fetch.addFetchParameter("ROW"); } + ) + + ( + { fetch.addFetchParameter("ONLY"); } + | + { fetch.addFetchParameter("WITH TIES"); } + ) + ) + ) ) { return fetch; @@ -3280,7 +3442,7 @@ Expression AndExpression() : ( LOOKAHEAD(2) { boolean useOperator = false; } - ( | {useOperator=true;} ) + ( | {useOperator=true;} ) ( LOOKAHEAD(Condition(), {!interrupted}) right=Condition() @@ -3346,19 +3508,25 @@ Expression RegularCondition() #RegularCondition: [ "(" "+" ")" { oracleJoin=EqualsTo.ORACLE_JOIN_RIGHT; } ] - ( LOOKAHEAD(2) - ">" { result = new GreaterThan(); } - | "<" { result = new MinorThan(); } - | "=" { result = new EqualsTo(); } - | token= { result = new GreaterThanEquals(token.image); } - | token= { result = new MinorThanEquals(token.image); } - | token= { result = new NotEqualsTo(token.image); } - | token= { result = new NotEqualsTo(token.image); } - | "@@" { result = new Matches(); } - | "~" { result = new RegExpMatchOperator(RegExpMatchOperatorType.MATCH_CASESENSITIVE); } - | "~*" { result = new RegExpMatchOperator(RegExpMatchOperatorType.MATCH_CASEINSENSITIVE); } - | "!~" { result = new RegExpMatchOperator(RegExpMatchOperatorType.NOT_MATCH_CASESENSITIVE); } - | "!~*" { result = new RegExpMatchOperator(RegExpMatchOperatorType.NOT_MATCH_CASEINSENSITIVE); } + ( + LOOKAHEAD(2) + ">" { result = new GreaterThan(); } + | "<" { result = new MinorThan(); } + | "=" { result = new EqualsTo(); } + | token= { result = new GreaterThanEquals(token.image); } + | token= { result = new MinorThanEquals(token.image); } + | token= { result = new NotEqualsTo(token.image); } + | token= { result = new NotEqualsTo(token.image); } + | "*=" { result = new TSQLLeftJoin(); } + | "=*" { result = new TSQLRightJoin(); } + | token= { result = new DoubleAnd(); } + | token= { result = new Contains(); } + | token= { result = new ContainedBy(); } + | "@@" { result = new Matches(); } + | "~" { result = new RegExpMatchOperator(RegExpMatchOperatorType.MATCH_CASESENSITIVE); } + | "~*" { result = new RegExpMatchOperator(RegExpMatchOperatorType.MATCH_CASEINSENSITIVE); } + | "!~" { result = new RegExpMatchOperator(RegExpMatchOperatorType.NOT_MATCH_CASESENSITIVE); } + | "!~*" { result = new RegExpMatchOperator(RegExpMatchOperatorType.NOT_MATCH_CASEINSENSITIVE); } | "@>" { result = new JsonOperator("@>"); } | "<@" { result = new JsonOperator("<@"); } @@ -3378,7 +3546,7 @@ Expression RegularCondition() #RegularCondition: [ LOOKAHEAD(2) "(" "+" ")" { oracleJoin=EqualsTo.ORACLE_JOIN_LEFT; } ] { - BinaryExpression regCond = (BinaryExpression) result; + BinaryExpression regCond = (BinaryExpression) result; regCond.setLeftExpression(leftExpression); regCond.setRightExpression(rightExpression); @@ -3433,7 +3601,8 @@ Expression InExpression() #InExpression : { Token token; int oldOracleJoin = 0; - boolean usesNot = false; + boolean usingNot = false; + boolean usingGlobal = false; Expression leftExpression; Expression rightExpression; } @@ -3441,7 +3610,9 @@ Expression InExpression() #InExpression : leftExpression=SimpleExpression() [ "(" "+" ")" { oldOracleJoin=EqualsTo.ORACLE_JOIN_RIGHT; } ] - [ { usesNot=true; } ] + [ { usingGlobal=true; } ] + [ { usingNot=true; } ] + ( LOOKAHEAD(2) token= { rightExpression = new StringValue(token.image); } | LOOKAHEAD(3) rightExpression = Function() @@ -3452,7 +3623,8 @@ Expression InExpression() #InExpression : { InExpression inExpression = new InExpression(leftExpression, rightExpression) .withOldOracleJoinSyntax(oldOracleJoin) - .withNot(usesNot); + .withNot(usingNot) + .setGlobal(usingGlobal); linkAST(inExpression,jjtThis); return inExpression; } @@ -3466,7 +3638,27 @@ Expression Between(Expression leftExpression) : } { [ { result.setNot(true); }] - betweenExpressionStart=SimpleExpression() betweenExpressionEnd=SimpleExpression() + + ( + LOOKAHEAD( 3 ) betweenExpressionStart = ParenthesedSelect() + | + LOOKAHEAD( SimpleFunction() ) betweenExpressionStart = SimpleFunction() + | + LOOKAHEAD( RegularCondition() ) betweenExpressionStart = RegularCondition() + | + betweenExpressionStart = SimpleExpression() + ) + + + ( + LOOKAHEAD( 3 ) betweenExpressionEnd = ParenthesedSelect() + | + LOOKAHEAD( SimpleFunction() ) betweenExpressionEnd = SimpleFunction() + | + LOOKAHEAD( RegularCondition() ) betweenExpressionEnd = RegularCondition() + | + betweenExpressionEnd = SimpleExpression() + ) { result.setLeftExpression(leftExpression); @@ -3813,7 +4005,10 @@ Expression SimpleExpression(): user = UserVariable() ( operation = "=" | operation = ":=" ) ] - retval=ConcatExpression() + + ( + retval=ConcatExpression() + ) ) { if (user != null) { @@ -4000,6 +4195,8 @@ Expression PrimaryExpression() #PrimaryExpression: boolean exclamationMarkNot = false; boolean dateExpressionAllowed = true; ExpressionList list; + + final List> jsonIdents = new ArrayList>(); } { [ { not=true; } | "!" { not=true; exclamationMarkNot=true; } ] @@ -4023,17 +4220,13 @@ Expression PrimaryExpression() #PrimaryExpression: | retval=XMLSerializeExpr() - | LOOKAHEAD(JsonExpression(), {!interrupted}) retval=JsonExpression() - - | LOOKAHEAD(JsonFunction(), {!interrupted}) retval = JsonFunction() + | LOOKAHEAD(3, { !interrupted}) retval = JsonFunction() - | LOOKAHEAD(JsonAggregateFunction(), {!interrupted}) retval = JsonAggregateFunction() + | LOOKAHEAD(3, { !interrupted}) retval = JsonAggregateFunction() - /* | LOOKAHEAD(FunctionWithCondParams()) retval = FunctionWithCondParams() */ + | LOOKAHEAD(3, { !interrupted}) retval = FullTextSearch() - | LOOKAHEAD(FullTextSearch(), {!interrupted}) retval = FullTextSearch() - - | LOOKAHEAD(Function(), {!interrupted}) retval=Function() [ LOOKAHEAD(2) retval = AnalyticExpression( (Function) retval ) ] + | LOOKAHEAD(Function(), { !interrupted}) retval=Function() [ LOOKAHEAD(2) retval = AnalyticExpression( (Function) retval ) ] | LOOKAHEAD(2, {!interrupted}) retval = IntervalExpression() { dateExpressionAllowed = false; } @@ -4097,12 +4290,28 @@ Expression PrimaryExpression() #PrimaryExpression: [ retval = ArrayExpression(retval) ] ( "::" type=ColDataType() { - castExpr = new CastExpression(); - castExpr.setUseCastKeyword(false); - castExpr.setLeftExpression(retval); - castExpr.setColDataType(type); - retval=castExpr; - } )* + castExpr = new CastExpression(); + castExpr.setUseCastKeyword(false); + castExpr.setLeftExpression(retval); + castExpr.setColDataType(type); + retval=castExpr; + } + )* + + // Check for JSON operands + [ + LOOKAHEAD(2) ( + "->" (token= | token=) { jsonIdents.add(new AbstractMap.SimpleEntry(token.image,"->")); } + | + "->>" (token= | token=) { jsonIdents.add(new AbstractMap.SimpleEntry(token.image,"->>")); } + | + "#>" token= { jsonIdents.add(new AbstractMap.SimpleEntry(token.image,"#>")); } + | + "#>>" token= { jsonIdents.add(new AbstractMap.SimpleEntry(token.image,"#>>")); } + )+ + retval = JsonExpression(retval, jsonIdents) + ] + ( LOOKAHEAD(2) timezoneRightExpr=PrimaryExpression() { if (timezoneExpr == null) @@ -4258,65 +4467,13 @@ Expression ParenthesedExpression(): } } -JsonExpression JsonExpression() : { - JsonExpression result = new JsonExpression(); - Expression expr; +JsonExpression JsonExpression(Expression expr, List> idents) : { + JsonExpression result = new JsonExpression(expr, idents); Token token; ColDataType type = null; CastExpression castExpr = null; } { - ( - LOOKAHEAD(3, {!interrupted}) expr=CaseWhenExpression() - | - expr = SimpleJdbcParameter() - | - LOOKAHEAD(2, {!interrupted}) expr=JdbcNamedParameter() - | - expr=UserVariable() - | - LOOKAHEAD(JsonFunction(), {getAsBoolean(Feature.allowComplexParsing) && !interrupted}) expr = JsonFunction() - | - LOOKAHEAD(JsonAggregateFunction(), {getAsBoolean(Feature.allowComplexParsing) && !interrupted}) expr = JsonAggregateFunction() - | - LOOKAHEAD(FullTextSearch(), {getAsBoolean(Feature.allowComplexParsing) && !interrupted}) expr = FullTextSearch() - | - LOOKAHEAD( Function() , {getAsBoolean(Feature.allowComplexParsing) && !interrupted} ) expr=Function() - | - LOOKAHEAD( 2, {!interrupted} ) expr=Column() - | - token= { expr = new StringValue(token.image); } - | - LOOKAHEAD(ParenthesedExpression(), {getAsBoolean(Feature.allowComplexParsing)} ) expr = ParenthesedExpression() - | - LOOKAHEAD( 3, {getAsBoolean(Feature.allowComplexParsing) && !interrupted}) expr=ParenthesedSelect() - ) - - ( - "::" type=ColDataType() - { - castExpr = new CastExpression(); - castExpr.setUseCastKeyword(false); - castExpr.setLeftExpression(expr); - castExpr.setColDataType(type); - expr=castExpr; - } - )* - { - result.setExpression(expr); - } - - ( - LOOKAHEAD(2) ( - "->" (token= | token=) {result.addIdent(token.image,"->");} - | - "->>" (token= | token=) {result.addIdent(token.image,"->>");} - | - "#>" token= {result.addIdent(token.image,"#>");} - | - "#>>" token= {result.addIdent(token.image,"#>>");} - ) - )+ // chaining JSON Expressions, e.g. // '{"obj":{"field": "value"}}'::JSON -> 'obj'::TEXT ->> 'field'::TEXT @@ -4334,8 +4491,7 @@ JsonExpression JsonExpression() : { ) )+ { - result = new JsonExpression(); - result.setExpression(expr); + result = new JsonExpression(expr); } ( @@ -4781,7 +4937,7 @@ CastExpression CastExpression(): expression=SimpleExpression() { retval.setUseCastKeyword(true); } ( - ( + LOOKAHEAD(2) ( "(" columnDefinition=ColumnDefinition() { retval.addColumnDefinition(columnDefinition); } @@ -4809,7 +4965,7 @@ Expression CaseWhenExpression() #CaseWhenExpression: } { { caseCounter++; } - [ switchExp=Expression() ] + [ LOOKAHEAD(2) switchExp=Expression() ] ( clause=WhenThenSearchCondition() { whenClauses.add(clause); } )+ [ @@ -4935,17 +5091,18 @@ FullTextSearch FullTextSearch() : { Function Function() #Function: { - Function retval = new Function(); + Function function; } { ( - "{" { retval.setEscaped(true); } InternalFunction(retval) "}" - | LOOKAHEAD(3) retval = SpecialStringFunctionWithNamedParameters() - | InternalFunction(retval) + "{" function = InternalFunction(true) "}" + | LOOKAHEAD( SimpleFunction(), { getAsBoolean(Feature.allowComplexParsing) }) function = SimpleFunction() + | LOOKAHEAD(3) function = SpecialStringFunctionWithNamedParameters() + | function = InternalFunction(false) ) { - linkAST(retval,jjtThis); - return retval; + linkAST(function,jjtThis); + return function; } } @@ -4975,15 +5132,49 @@ Function SpecialStringFunctionWithNamedParameters() : } } -Function InternalFunction(Function retval) : +// a simplified function with only one parameter +// useful for parsing nested functions fast +Function SimpleFunction(): +{ + List name; + Expression expr=null; +} +{ + name = RelObjectNameList() + "(" + [ + ( + "*" { expr = new AllColumns(); } + | + LOOKAHEAD( AllTableColumns() ) expr=AllTableColumns() + | + LOOKAHEAD( 3 ) expr = ParenthesedSelect() + | + LOOKAHEAD( SimpleFunction() ) expr = SimpleFunction() + | + LOOKAHEAD( RegularCondition() ) expr = RegularCondition() + | + LOOKAHEAD( SimpleExpressionList() ) expr = SimpleExpressionList() + ) + ] + ")" + { + Function function = new Function().withName(name); + if (expr!=null) { + function.setParameters(expr); + } + + return function; + } +} + +Function InternalFunction(boolean escaped): { + Function retval = new Function(); List funcName; - Expression allColumnsExpression = null; ExpressionList expressionList = null; KeepExpression keep = null; - Select expr = null; - Token tk1 = null; - Token tk2 = null; + Expression expr = null; Expression attributeExpression = null; Column attributeColumn = null; List orderByList; @@ -5002,10 +5193,6 @@ Function InternalFunction(Function retval) : ) ] ( - "*" { expressionList = new ExpressionList(new AllColumns()); } - | - LOOKAHEAD( AllTableColumns() ) allColumnsExpression=AllTableColumns() { expressionList = new ExpressionList(allColumnsExpression); } - | LOOKAHEAD(3) expressionList=ExpressionList() [ orderByList = OrderByElements() { retval.setOrderByElements(orderByList); } ] | expr = Select() { expressionList = new ExpressionList(expr); } @@ -5027,6 +5214,7 @@ Function InternalFunction(Function retval) : [ LOOKAHEAD(2) keep = KeepExpression() ] { + retval.setEscaped(escaped); retval.setParameters(expressionList); retval.setName(funcName); retval.setKeep(keep); @@ -5041,9 +5229,9 @@ XMLSerializeExpr XMLSerializeExpr(): { ColDataType dataType; } { - - "(" - "(" + + "(" + "(" "(" expression=SimpleExpression() ")" [ orderByElements=OrderByElements() ] ")" @@ -5126,7 +5314,7 @@ List ColumnNamesWithParamsList() : { Index Index(): { List name; -} +} { name= RelObjectNameList() { return new Index().withName(name).withType(""); } } @@ -5136,10 +5324,8 @@ CreateIndex CreateIndex(): CreateIndex createIndex = new CreateIndex(); Table table = null; List colNames; - //Token columnName; Token using; Index index = null; - //String name = null; List parameter = new ArrayList(); List tailParameters = new ArrayList(); List name; @@ -5147,18 +5333,26 @@ CreateIndex CreateIndex(): { [ parameter=CreateParameter() ] - index = Index() { index.setType(parameter.isEmpty()?null:parameter.get(0)); } - - table=Table() - - [ using= {index.setUsing(using.image);} ] - + + [ LOOKAHEAD(2) { createIndex.setUsingIfNotExists(true);} ] + index = Index() { index.setType(parameter.isEmpty() ? null : parameter.get(0)); } + ( + LOOKAHEAD(3)( + table=Table() + [ using= { index.setUsing(using.image); } ] + ) + | + ( + [ using= { + index.setUsing(using.image); + createIndex.setIndexTypeBeforeOn(true); + } + ] + table=Table() + ) + ) colNames = ColumnNamesWithParamsList() - - /* [ tailParameter = CreateParameter() {} ] */ - ( parameter=CreateParameter() { tailParameters.addAll(parameter); } )* - { index.setColumns(colNames); createIndex.setIndex(index); @@ -5292,8 +5486,8 @@ CreateTable CreateTable(boolean isUsingOrReplace): [ LOOKAHEAD(2) { createTable.setIfNotExists(true); }] table=Table() - [ LOOKAHEAD(2) ( - LOOKAHEAD(3) + [ LOOKAHEAD(2) ( + LOOKAHEAD(3) ("(" tableColumn=RelObjectName() { columns.add(tableColumn); } ("," tableColumn=RelObjectName() { columns.add(tableColumn); } )* ")") | ("(" @@ -5481,6 +5675,8 @@ ColDataType ColDataType(): ColDataType colDataType = new ColDataType(); Token tk = null; Token tk2 = null; + String schema; + String type; List argumentsStringList = new ArrayList(); List array = new ArrayList(); List name; @@ -5488,7 +5684,7 @@ ColDataType ColDataType(): } { ( - tk= ( + LOOKAHEAD(2) tk= ( ("<" arrayType = ColDataType() ">") { colDataType.setDataType("ARRAY<" + arrayType.getDataType() + ">"); } @@ -5499,16 +5695,35 @@ ColDataType ColDataType(): | tk= "(" (tk2= | tk2=) ")" | tk= "(" (tk2= | tk2=) ")" ) { colDataType.setDataType(tk.image + " (" + tk2.image + ")"); } - | (tk= | tk=) [tk2=] { colDataType.setDataType(tk.image + (tk2!=null?" " + tk2.image:"")); } - | tk= [LOOKAHEAD(2) tk2=] { colDataType.setDataType(tk.image + (tk2!=null?" " + tk2.image:"")); } - | ( tk= | tk= | tk= | tk= | tk= | tk= - | tk= | tk= | tk= | tk= | tk= | tk= ) - [ "." (tk2= | tk2=) ] - { if (tk2!=null) colDataType.setDataType(tk.image + "." + tk2.image); else colDataType.setDataType(tk.image); } - | tk= [LOOKAHEAD(2) tk2=] - { if (tk2!=null) colDataType.setDataType(tk.image + " " + tk2.image); else colDataType.setDataType(tk.image); } - | LOOKAHEAD(2) tk= tk2= {colDataType.setDataType(tk.image + " " + tk2.image);} - | tk= { colDataType.setDataType(tk.image);} + | + LOOKAHEAD(2) (tk= | tk=) [tk2=] { colDataType.setDataType(tk.image + (tk2!=null?" " + tk2.image:"")); } + | + tk= [LOOKAHEAD(2) tk2=] { colDataType.setDataType(tk.image + (tk2!=null?" " + tk2.image:"")); } + | + ( + tk= + | tk= + | tk= + | tk= + | tk= + | tk= + | tk= + | tk= + | tk= + | tk= + | tk= + | tk= + | tk= + ) { schema = tk.image; } + [ "." type = RelObjectName() { schema += "." + type; } ] + { colDataType.setDataType(schema); } + | + tk= [LOOKAHEAD(2) tk2=] + { if (tk2!=null) colDataType.setDataType(tk.image + " " + tk2.image); else colDataType.setDataType(tk.image); } + | + LOOKAHEAD(2) tk= tk2= {colDataType.setDataType(tk.image + " " + tk2.image);} + | + tk= { colDataType.setDataType(tk.image);} ) [LOOKAHEAD(2) "(" {tk2 =null;} ( ( ( tk= [ LOOKAHEAD(2) (tk2= | tk2=) ] ) | tk= | tk= | tk= ) @@ -5538,13 +5753,30 @@ Analyze Analyze(): } } +ExpressionList ColumnWithCommentList(): +{ + ExpressionList expressions = new ExpressionList(); + Column img = null; +} +{ + "(" + img=Column() { expressions.add(img); } + ( "," img=Column() { expressions.add(img); } )* + ")" + { + return expressions; + } +} + + CreateView CreateView(boolean isUsingOrReplace): { CreateView createView = new CreateView(); Table view = null; Select select = null; - List columnNames = null; + ExpressionList columnNames = null; Token tk = null; + List commentTokens = null; } { { createView.setOrReplace(isUsingOrReplace);} @@ -5560,13 +5792,36 @@ CreateView CreateView(boolean isUsingOrReplace): view=Table() { createView.setView(view); } [LOOKAHEAD(3) (tk= | tk=) { createView.setAutoRefresh(AutoRefreshOption.from(tk.image)); } ] [LOOKAHEAD(3) {createView.setIfNotExists(true);}] - [ columnNames = ColumnsNamesList() { createView.setColumnNames(columnNames); } ] + [ columnNames=ColumnWithCommentList( ) { createView.setColumnNames(columnNames); } ] + [ commentTokens=CreateViewTailComment( ) { createView.setViewCommentOptions(commentTokens); } ] select=Select( ) { createView.setSelect(select); } [ { createView.setWithReadOnly(true); } ] { return createView; } } +List CreateViewTailComment(): +{ + Token tk = null; + Token tk2 = null; + String op = null; + List result = new ArrayList(); +} +{ + tk= + [ "=" { op = "="; } ] + tk2 = { + result.add(""); + result.add(tk.image); + if (op != null) { + result.add(op); + } + result.add(tk2.image); + } + { return result;} +} + + ReferentialAction.Action Action(): { ReferentialAction.Action action = null; @@ -5611,7 +5866,6 @@ List CreateParameter(): Token tk = null, tk2 = null; Expression exp = null; ColDataType colDataType; - List param = new ArrayList(); } { @@ -5645,7 +5899,7 @@ List CreateParameter(): | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= | tk= - | tk= + | tk= | tk= | tk= | tk= | tk= | tk="=" ) { param.add(tk.image); } @@ -5864,7 +6118,7 @@ AlterExpression.ColumnDataType AlterExpressionColumnDataType(): } { columnName = RelObjectName() - ( { withType = true; } )? + ( LOOKAHEAD(2) { withType = true; } )? dataType = ColDataType() { columnSpecs = new ArrayList(); } ( parameter = CreateParameter() { columnSpecs.addAll(parameter); } )* { @@ -5940,6 +6194,18 @@ List AlterExpressionConstraintState(): } } +Index IndexWithComment(Index index): +{ + Token tk = null; +} +{ + tk= { + index.setCommentText(tk.image); + } + { + return index; + } +} /** * This production needs refactoring to multiple smaller productions. The target class should @@ -5971,17 +6237,15 @@ AlterExpression AlterExpression(): ( ( ( - { alterExp.setOperation(AlterOperation.ADD); } + { alterExp.setOperation(AlterOperation.ADD); } | - { alterExp.setOperation(AlterOperation.ALTER); } + { alterExp.setOperation(AlterOperation.ALTER); } | { alterExp.setOperation(AlterOperation.MODIFY); } ) ( - LOOKAHEAD(2) ( - columnNames=ColumnsNamesList() { alterExp.setPkColumns(columnNames); } - ) + LOOKAHEAD(2) ( columnNames=ColumnsNamesList() { alterExp.setPkColumns(columnNames); }) constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] @@ -5996,6 +6260,7 @@ AlterExpression AlterExpression(): } constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] + [ index = IndexWithComment(index) { alterExp.setIndex(index); } ] ) | LOOKAHEAD(3) ( @@ -6003,47 +6268,50 @@ AlterExpression AlterExpression(): ( LOOKAHEAD(4) ( - "(" { alterExp.useBrackets(true);} + "(" + { alterExp.useBrackets(true);} alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); } ( "," alterExpressionColumnDataType = AlterExpressionColumnDataType() { - alterExp.addColDataType(alterExpressionColumnDataType); - } + alterExp.addColDataType(alterExpressionColumnDataType); + } )* - ")" - ) + ")" + ) | - LOOKAHEAD(2) alterExpressionColumnDataType = AlterExpressionColumnDataType() { - alterExp.addColDataType(alterExpressionColumnDataType); - } + LOOKAHEAD(2) alterExpressionColumnDataType = AlterExpressionColumnDataType() + { alterExp.addColDataType(alterExpressionColumnDataType); } | - LOOKAHEAD(3) alterExpressionColumnDropNotNull = AlterExpressionColumnDropNotNull() { - alterExp.addColDropNotNull( alterExpressionColumnDropNotNull); - } + LOOKAHEAD(3) alterExpressionColumnDropNotNull = AlterExpressionColumnDropNotNull() + { alterExp.addColDropNotNull( alterExpressionColumnDropNotNull);} | - alterExpressionColumnDropDefault = AlterExpressionColumnDropDefault() { - alterExp.addColDropDefault( alterExpressionColumnDropDefault); - } + alterExpressionColumnDropDefault = AlterExpressionColumnDropDefault() + { alterExp.addColDropDefault( alterExpressionColumnDropDefault); } ) ) | ( "(" alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); } - ("," alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); } )* ")" + ("," + alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); } + )* + ")" ) | ( (( { alterExp.setUk(true); } | ) (tk= | tk=) { alterExp.setUkName(tk.image); } )? columnNames=ColumnsNamesList() { alterExp.setUkColumns(columnNames); } - [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }]) + [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] + [ index = IndexWithComment(index) { alterExp.setIndex(index); } ] + ) | //following two choices regarding foreign keys should be merged ( columnNames=ColumnsNamesList() { alterExp.setFkColumns(columnNames); columnNames = null; } /* tk= [ columnNames=ColumnsNamesList() ] - { alterExp.setFkSourceTable(tk.image); alterExp.setFkSourceColumns(columnNames); } + { alterExp.setFkSourceTable(tk.image); alterExp.setFkSourceColumns(columnNames); } */ fkTable=Table() [ columnNames=ColumnsNamesList() ] { @@ -6053,17 +6321,17 @@ AlterExpression AlterExpression(): } [LOOKAHEAD(2) ( (tk= | tk=) action = Action() - { alterExp.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } - )] + { alterExp.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } + )] [LOOKAHEAD(2) ( (tk= | tk=) action = Action() - { alterExp.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } - )] + { alterExp.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } + )] ) | ( sk3=RelObjectName() - - ( ( tk= tk2= + ( + ( tk= tk2= columnNames=ColumnsNamesList() { fkIndex = new ForeignKeyIndex() @@ -6078,12 +6346,12 @@ AlterExpression AlterExpression(): alterExp.setIndex(fkIndex); } - [LOOKAHEAD(2) ( (tk= | tk=) action = Action() - { fkIndex.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } - )] - [LOOKAHEAD(2) ( (tk= | tk=) action = Action() - { fkIndex.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } - )] + [LOOKAHEAD(2) ( (tk= | tk=) action = Action() + { fkIndex.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } + )] + [LOOKAHEAD(2) ( (tk= | tk=) action = Action() + { fkIndex.setReferentialAction(ReferentialAction.Type.from(tk.image), action); } + )] constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } ) | @@ -6098,13 +6366,14 @@ AlterExpression AlterExpression(): } constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] + [ index = IndexWithComment(index) { alterExp.setIndex(index); } ] ) | ( {Expression exp = null;} ("(" exp = Expression() ")")* { - CheckConstraint checkCs = new CheckConstraint().withName(sk3).withExpression(exp); - alterExp.setIndex(checkCs); - } + CheckConstraint checkCs = new CheckConstraint().withName(sk3).withExpression(exp); + alterExp.setIndex(checkCs); + } ) | ( @@ -6119,28 +6388,25 @@ AlterExpression AlterExpression(): } constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } [ sk4=RelObjectName() { alterExp.addParameters("USING", sk4); }] + [ index = IndexWithComment(index) { alterExp.setIndex(index); } ] ) | ( tk= - columnNames=ColumnsNamesList() - { - index = new NamedConstraint() - .withName(sk3) - .withType(tk.image) - .withColumnsNames(columnNames); - alterExp.setIndex(index); - } - constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } + columnNames=ColumnsNamesList() + { + index = new NamedConstraint() + .withName(sk3) + .withType(tk.image) + .withColumnsNames(columnNames); + alterExp.setIndex(index); + } + constraints=AlterExpressionConstraintState() { alterExp.setConstraints(constraints); } ) - ) + ) ) | - ( sk3=RelObjectName() - tk= { - alterExp.withColumnName(sk3).withCommentText(tk.image); - } - ) + ( sk3=RelObjectName() tk= { alterExp.withColumnName(sk3).withCommentText(tk.image); } ) ) ) | @@ -6153,7 +6419,7 @@ AlterExpression AlterExpression(): ) ) | - { alterExp.setOperation(AlterOperation.DROP); } + { alterExp.setOperation(AlterOperation.DROP); } ( ( ( @@ -6184,11 +6450,11 @@ AlterExpression AlterExpression(): ) | ( - tk= + ( tk= | tk= ) ( tk2= | tk2= ) { - index = new Index().withType(tk.image).withName(tk2.image); - alterExp.setIndex(index); - } + index = new Index().withType(tk.image).withName(tk2.image); + alterExp.setIndex(index); + } ) | ( @@ -6215,34 +6481,50 @@ AlterExpression AlterExpression(): ) ) | - ( - { + ( + { alterExp.setOperation(AlterOperation.ALGORITHM); } ["=" { alterExp.setUseEqual(true);} ] sk3 = RelObjectName() {alterExp.addParameters(sk3); } - ) + ) | - LOOKAHEAD(2) { alterExp.setOperation(AlterOperation.RENAME); } [ { alterExp.hasColumn(true);} ] - ( tk= | tk= ) { alterExp.setColOldName(tk.image); } + LOOKAHEAD(2) { alterExp.setOperation(AlterOperation.RENAME); } [ { alterExp.hasColumn(true);} ] + ( tk= | tk= ) { alterExp.setColOldName(tk.image); } - (tk2= | tk2=) { alterExp.setColumnName(tk2.image); } + (tk2= | tk2=) { alterExp.setColumnName(tk2.image); } | - ( + LOOKAHEAD(2)( {alterExp.setOperation(AlterOperation.RENAME_TABLE);} - (tk2= | tk2=) { alterExp.setNewTableName(tk2.image);} + (tk2= | tk2=) { alterExp.setNewTableName(tk2.image);} ) | ( {alterExp.setOperation(AlterOperation.COMMENT);} + ["=" {alterExp.setOperation(AlterOperation.COMMENT_WITH_EQUAL_SIGN);} ] tk= { alterExp.setCommentText(tk.image); } ) | - tokens = captureRest() { + LOOKAHEAD(2) + ( (( {alterExp.setOperation(AlterOperation.RENAME_INDEX);} + | {alterExp.setOperation(AlterOperation.RENAME_KEY);}) + | { alterExp.setOperation(AlterOperation.RENAME_CONSTRAINT); } + ) + (tk= | tk=){ + alterExp.setOldIndex(new Index().withName(tk.image)); + } + + (tk2= | tk2=){ + index = new Index().withName(tk2.image); + alterExp.setIndex(index); + } + ) + | + tokens = captureRest() { alterExp.setOperation(AlterOperation.UNSPECIFIC); StringBuilder optionalSpecifier = new StringBuilder(); int i=0; - for (String s: tokens) + for (String s: tokens) if (! (s.equals(";") || s.equals("\n\n\n")) ) { if (i>0) optionalSpecifier.append( " " ); @@ -6251,7 +6533,7 @@ AlterExpression AlterExpression(): } alterExp.setOptionalSpecifier( optionalSpecifier.toString() ); - } + } ) { @@ -6337,18 +6619,18 @@ AlterSession AlterSession(): } { ( - ( + ( ( { operation = AlterSessionOperation.ADVISE_COMMIT; } | { operation = AlterSessionOperation.ADVISE_ROLLBACK; } | { operation = AlterSessionOperation.ADVISE_NOTHING; } ) ) | - ( + ( { operation = AlterSessionOperation.CLOSE_DATABASE_LINK; } ) - | - ( + | + ( ( { operation = AlterSessionOperation.ENABLE_COMMIT_IN_PROCEDURE; } | { operation = AlterSessionOperation.ENABLE_GUARD; } | ( { operation = AlterSessionOperation.ENABLE_PARALLEL_DML; } @@ -6359,7 +6641,7 @@ AlterSession AlterSession(): ) ) | - ( + ( ( { operation = AlterSessionOperation.DISABLE_COMMIT_IN_PROCEDURE; } | { operation = AlterSessionOperation.DISABLE_GUARD; } | ( { operation = AlterSessionOperation.DISABLE_PARALLEL_DML; } @@ -6370,19 +6652,19 @@ AlterSession AlterSession(): ) ) | - ( + ( ( { operation = AlterSessionOperation.FORCE_PARALLEL_DML; } | { operation = AlterSessionOperation.FORCE_PARALLEL_DDL; } | { operation = AlterSessionOperation.FORCE_PARALLEL_QUERY; } ) ) | - ( + ( { operation = AlterSessionOperation.SET; } ) ) - ( ( token = + ( ( token = | token = | token = "=" | token = @@ -6403,37 +6685,37 @@ AlterSystemStatement AlterSystemStatement(): } { ( - ( + ( "ARCHIVE" "LOG" { operation = AlterSystemOperation.ARCHIVE_LOG; } ) | - ( + ( "CHECKPOINT" { operation = AlterSystemOperation.CHECKPOINT; } ) | - ( + ( "DUMP" "ACTIVE" "SESSION" "HISTORY" { operation = AlterSystemOperation.DUMP_ACTIVE_SESSION_HISTORY; } ) - | - ( - ( + | + ( + ( "DISTRIBUTED RECOVERY" { operation = AlterSystemOperation.ENABLE_DISTRIBUTED_RECOVERY; } | "RESTRICTED SESSION" { operation = AlterSystemOperation.ENABLE_DISTRIBUTED_RECOVERY; } ) ) | - ( - ( + ( + ( "DISTRIBUTED RECOVERY" { operation = AlterSystemOperation.DISABLE_DISTRIBUTED_RECOVERY; } | "RESTRICTED SESSION" { operation = AlterSystemOperation.DISABLE_RESTRICTED_SESSION; } ) ) | - ( + ( "FLUSH" { operation = AlterSystemOperation.FLUSH; } ) | - ( + ( "DISCONNECT" "SESSION" { operation = AlterSystemOperation.DISCONNECT_SESSION; } ) | @@ -6441,39 +6723,39 @@ AlterSystemStatement AlterSystemStatement(): "KILL SESSION" { operation = AlterSystemOperation.KILL_SESSION; } ) | - ( + ( "SWITCH" { operation = AlterSystemOperation.SWITCH; } ) | - ( + ( "SUSPEND" { operation = AlterSystemOperation.SUSPEND; } ) | - ( + ( "RESUME" { operation = AlterSystemOperation.RESUME; } ) | - ( + ( "QUIESCE" "RESTRICTED" { operation = AlterSystemOperation.QUIESCE; } ) | ( - "UNQUIESCE" { operation = AlterSystemOperation.UNQUIESCE; } + { operation = AlterSystemOperation.UNQUIESCE; } ) | - ( + ( "SHUTDOWN" { operation = AlterSystemOperation.SHUTDOWN; } ) | - ( + ( "REGISTER" { operation = AlterSystemOperation.REGISTER; } ) | - ( + ( "SET" { operation = AlterSystemOperation.SET; } ) | - ( + ( "RESET" { operation = AlterSystemOperation.RESET; } ) ) @@ -6523,14 +6805,14 @@ RollbackStatement RollbackStatement(): { rollbackStatement = new RollbackStatement(); } [ { rollbackStatement.setUsingWorkKeyword(true); } ] [ ( - [ { rollbackStatement.setUsingSavepointKeyword(true); }] + [ { rollbackStatement.setUsingSavepointKeyword(true); }] token= { rollbackStatement.setSavepointName(token.image); } ) | ( token= { rollbackStatement.setForceDistributedTransactionIdentifier(token.image); } ) ] - + { return rollbackStatement; } diff --git a/src/main/resources/rr/xhtml2rst.xsl b/src/main/resources/rr/xhtml2rst.xsl index 5d0132bad..b29b03413 100644 --- a/src/main/resources/rr/xhtml2rst.xsl +++ b/src/main/resources/rr/xhtml2rst.xsl @@ -21,11 +21,14 @@ omit-xml-declaration="yes" indent="no" /> - + + - + + + .. raw:: html <div id="floating-toc"> @@ -36,18 +39,26 @@ <ul id="toc-list"></ul> </div> - + + + ********************************************************************* -SQL Syntax |JSQLPARSER_SNAPSHOT_VERSION| +SQL Syntax + |JSQLPARSER_SNAPSHOT_VERSION| + |JSQLPARSER_VERSION| + ********************************************************************* -The EBNF and Railroad Diagrams for JSQLParser-|JSQLPARSER_VERSION|. +The EBNF and Railroad Diagrams for + |JSQLPARSER_SNAPSHOT_VERSION| + |JSQLPARSER_VERSION| + . diff --git a/src/site/sphinx/changelog.rst b/src/site/sphinx/changelog.rst deleted file mode 100644 index 9d98f0d37..000000000 --- a/src/site/sphinx/changelog.rst +++ /dev/null @@ -1,1217 +0,0 @@ - -************************ -Changelog -************************ - - -Latest Changes since |JSQLPARSER_VERSION| -============================================================= - - - * **feat: BigQuery Except(..) Replace(..) syntax** - - Andreas Reichel, 2023-09-01 - * **test: add test for Postgres `NOTNULL` expression** - - Andreas Reichel, 2023-08-31 - * **build: Disable Signing with in Memory keys temporarily** - - Andreas Reichel, 2023-08-29 - * **fix: ExpressionList of Expressions in `Values`** - - Andreas Reichel, 2023-08-26 - * **style: add license headers** - - Andreas Reichel, 2023-08-23 - * **feat: implement a few missing expressions** - - Andreas Reichel, 2023-08-23 - * **fix: check for NULL before iterating** - - Andreas Reichel, 2023-08-23 - * **doc: explain the TablesNamesFinder, fix the example** - - Andreas Reichel, 2023-08-20 - * **doc: explain the TablesNamesFinder** - - Andreas Reichel, 2023-08-20 - * **Fixing a problem with an OP_CONCAT in WhenExpression (#1837)** - - amigalev, 2023-08-20 - * **refactor: TablesNamesFinder** - - Andreas Reichel, 2023-08-20 - * **build: disable Gradle publish** - - Andreas Reichel, 2023-08-20 - * **refactor: TableFunction extends Function, supports `LATERAL` prefix** - - Andreas Reichel, 2023-08-20 - * **Update Gradle JavaCC parser to latest version (3.0.0) (#1843)** - - Zbynek Konecny, 2023-08-05 - * **Update sql-parser-error.md** - - manticore-projects, 2023-07-26 - * **Update sql-parser-error.md** - - manticore-projects, 2023-07-26 - * **Update sql-parser-error.md** - - manticore-projects, 2023-07-25 - * **feat: SQL:2016 TABLESAMPLE clause** - - Andreas Reichel, 2023-07-12 - * **feat: add a method checking balanced brackets** - - Andreas Reichel, 2023-07-12 - * **build: publish Snapshots on commit** - - Andreas Reichel, 2023-07-12 - * **build: publish Snapshots on commit** - - Andreas Reichel, 2023-07-03 - * **build: publish Snapshots on commit** - - Andreas Reichel, 2023-07-02 - * **build: publish Snapshots on commit** - - Andreas Reichel, 2023-07-02 - * **build: publish Snapshots on commit** - - Andreas Reichel, 2023-07-02 - * **build: publish Snapshots on commit** - - Andreas Reichel, 2023-07-02 - * **feat: add support for INTERPRET function parsing (#1816)** - - Matteo Sist, 2023-06-29 - * **style: Licenses from Maven plugin** - - Andreas Reichel, 2023-06-27 - * **fix: Backslash escaped single quote `'\''`** - - Andreas Reichel, 2023-06-27 - * **Assorted Fixes #8 (#1807)** - - manticore-projects, 2023-06-15 - * **fix: `INSERT` must use simple Column Names only** - - Andreas Reichel, 2023-06-15 - * **feat: MySQL `NOT RLIKE`, `NOT REGEXP` expressions** - - Andreas Reichel, 2023-06-15 - * **feat: Postgres `NOTNULL` support** - - manticore-projects, 2023-06-15 - * **feat: `QUALIFY` clause** - - Andreas Reichel, 2023-06-15 - * **docs: write migration guide** - - Andreas Reichel, 2023-06-11 - * **fix: SPHINX modules and themes** - - Andreas Reichel, 2023-06-02 - * **feat: T-SQL `FOR ...` clause** - - Andreas Reichel, 2023-06-02 - * **doc: migration guide** - - Andreas Reichel, 2023-06-02 - * **fix: expose IntervalExpression attributes and use DeParser** - - Andreas Reichel, 2023-06-01 - * **Update sphinx.yml** - - manticore-projects, 2023-06-01 - * **JSQLParser 5.0 (#1778)** - - manticore-projects, 2023-06-01 - * **doc: write migration guide** - - Andreas Reichel, 2023-05-29 - * **fix: throw the specific exception** - - Andreas Reichel, 2023-05-29 - * **doc: Website, fix tabs** - - Andreas Reichel, 2023-05-24 - * **doc: Website improvements** - - Andreas Reichel, 2023-05-22 - * **build: improve Upload task** - - Andreas Reichel, 2023-05-19 - * **feat: Quoted Identifiers can contain double-quotes (PostgreSQL)** - - Andreas Reichel, 2023-05-18 - * **Create gradle.yml** - - manticore-projects, 2023-05-18 - * **feat: functions blocks, parenthesed JSON Expressions** - - Andreas Reichel, 2023-05-18 - * **feat: functions blocks, parenthesed JSON Expressions** - - Andreas Reichel, 2023-05-18 - * **feat: parse CREATE TRIGGER as UnsupportedStatement** - - Andreas Reichel, 2023-05-17 - * **build: try to work around the Maven/JDK8 issue on GitHub** - - Andreas Reichel, 2023-05-17 - * **refact: Statements extends List** - - Andreas Reichel, 2023-05-17 - * **style: remove unused imports** - - Andreas Reichel, 2023-05-17 - * **feat: chaining JSON Expressions** - - Andreas Reichel, 2023-05-17 - * **style: Cosmetic improvements** - - Andreas Reichel, 2023-05-17 - * **style: Quieten the logger** - - Andreas Reichel, 2023-05-17 - * **fix: Complex Parsing Approach** - - Andreas Reichel, 2023-05-17 - * **refactor: CREATE and ALTER productions** - - Andreas Reichel, 2023-05-16 - * **refactor: RETURNING clause** - - Andreas Reichel, 2023-05-16 - * **refactor: SHOW statement, supporting any RDBMS specific implementation** - - Andreas Reichel, 2023-05-16 - * **refactor: simplify production `CreateParameter()`** - - Andreas Reichel, 2023-05-16 - * **fix: issue #1789** - - Andreas Reichel, 2023-05-16 - * **fix: issue #1789** - - Andreas Reichel, 2023-05-16 - * **fix: issue #1791** - - Andreas Reichel, 2023-05-15 - * **build: improve the GIT Snapshot detection** - - Andreas Reichel, 2023-05-15 - * **build: Sphinx build fixes** - - Andreas Reichel, 2023-05-14 - * **build: Sphinx build fixes** - - Andreas Reichel, 2023-05-14 - * **build: Sphinx build fixes** - - Andreas Reichel, 2023-05-14 - * **Update sphinx.yml** - - manticore-projects, 2023-05-14 - * **feat: Write API documentation to the WebSite via XMLDoclet** - - Andreas Reichel, 2023-05-14 - * **test: add unit test for issue #1778** - - Andreas Reichel, 2023-05-11 - * **style: appease PMD/Codacy** - - Andreas Reichel, 2023-05-11 - * **style: appease PMD/Codacy** - - Andreas Reichel, 2023-05-11 - * **feat: `MEMBER OF` condition as shown at https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of** - - Andreas Reichel, 2023-05-11 - * **feat: access Elements of Array Columns** - - Andreas Reichel, 2023-05-11 - * **feat: JdbcNamedParameter allows "&" (instead of ":")** - - Andreas Reichel, 2023-05-11 - * **fix: Java Version 8** - - Andreas Reichel, 2023-05-09 - * **refactor: generify `SelectItem` and remove `FunctionItem` and `ExpressionListItem`** - - Andreas Reichel, 2023-05-09 - * **style: replace all List with ExpressionList<> and enforce policy via Acceptance Test** - - Andreas Reichel, 2023-05-09 - * **fix: find the correct position when field belongs to an internal class** - - Andreas Reichel, 2023-05-09 - * **style: Appease PMD** - - Andreas Reichel, 2023-05-07 - * **style: Appease Checkstyle** - - Andreas Reichel, 2023-05-07 - * **test: Disable API Sanitation for the moment** - - Andreas Reichel, 2023-05-07 - * **refactor: `Insert` uses `ExpressionList` and `UpdateSet`** - - Andreas Reichel, 2023-05-07 - * **build: improve Gradle Build** - - Andreas Reichel, 2023-05-07 - * **refactor: remove SimpleFunction** - - Andreas Reichel, 2023-05-06 - * **doc: RR chart colors cater for Dark Mode** - - Andreas Reichel, 2023-05-06 - * **doc: Better Sphinx Tabs** - - Andreas Reichel, 2023-05-06 - * **style: Rework all the ENUMs** - - Andreas Reichel, 2023-05-05 - * **style: Appease Codacy** - - Andreas Reichel, 2023-05-04 - * **refactor: Remove `ItemsList`, `MultiExpressionList`, `Replace`** - - Andreas Reichel, 2023-05-04 - * **style: Checkstyle** - - Andreas Reichel, 2023-05-03 - * **style: Appease Codacy** - - Andreas Reichel, 2023-05-03 - * **build: Increase TimeOut for the GitHub CI** - - Andreas Reichel, 2023-05-03 - * **refactor: UpdateSets for `Update` and `InsertConflictTarget`** - - Andreas Reichel, 2023-05-03 - * **fix: Remove tests for `()`, since `ParenthesedExpressionList` will catch those too** - - Andreas Reichel, 2023-05-03 - * **feat: Consolidate the `ExpressionList`, removing many redundant List alike Classes and Productions** - - Andreas Reichel, 2023-05-03 - * **Revert "fix: assign Enum case insensitive"** - - Andreas Reichel, 2023-05-02 - * **fix: assign Enum case insensitive** - - Andreas Reichel, 2023-05-02 - * **doc: Update the README.md** - - Andreas Reichel, 2023-05-01 - * **build: Add missing import** - - Andreas Reichel, 2023-04-30 - * **doc: Update examples** - - Andreas Reichel, 2023-04-30 - * **refactor: remove `SelectExpressionItem` in favor of `SelectItem`** - - Andreas Reichel, 2023-04-30 - * **test: add specific tests for closed issues** - - Andreas Reichel, 2023-04-30 - * **test: add specific tests for closed issues** - - Andreas Reichel, 2023-04-30 - * **feat: ClickHouse `LIMIT ... BY ...` clause** - - Andreas Reichel, 2023-04-30 - * **feat: implement SQL:2016 Convert() and Trim()** - - Andreas Reichel, 2023-04-30 - * **feat: Switch off contradicting `JOIN` qualifiers, when setting a qualifier** - - Andreas Reichel, 2023-04-30 - * **feat: Test if a JOIN is an INNER JOIN according to the SQL:2016** - - Andreas Reichel, 2023-04-30 - * **feat: ClickHouse `Select...` ``FINAL` modifier** - - Andreas Reichel, 2023-04-29 - * **feat: Multi-Part Names for Variables and Parameters** - - Andreas Reichel, 2023-04-29 - * **feat: Oracle `HAVING` before `GROUP BY`** - - Andreas Reichel, 2023-04-29 - * **feat: Lateral View** - - Andreas Reichel, 2023-04-29 - * **Fix #1758: Use long for Feature.timeOut (#1759)** - - Tomasz Zarna, 2023-04-27 - * **Ignoring unnecessarily generated jacoco report (#1762)** - - optimizing-ci-builds, 2023-04-27 - * **Ignoring unnecessarily generated by pmd plugin (#1763)** - - optimizing-ci-builds, 2023-04-27 - * **Refactor Parenthesed SelectBody and FromItem (#1754)** - - manticore-projects, 2023-04-27 - * **Assorted Fixes #7 (#1745)** - - manticore-projects, 2023-03-21 - * **disable xml report (#1748)** - - optimizing-ci-builds, 2023-03-21 - * **Assorted Fixes #6 (#1740)** - - manticore-projects, 2023-03-09 - * **test: commit missing test** - - Andreas Reichel, 2023-03-07 - * **style: apply Spotless** - - Andreas Reichel, 2023-03-07 - * **feat: FETCH uses EXPRESSION** - - Andreas Reichel, 2023-03-07 - * **version 4.7-SNAPSHOT** - - Tobias Warneke, 2023-02-23 - * **[maven-release-plugin] prepare for next development iteration** - - Tobias Warneke, 2023-02-23 - * **feat: Support more Statement Separators** - - Andreas Reichel, 2023-02-02 - * **Update issue templates** - - manticore-projects, 2023-02-01 - * **Update issue templates** - - manticore-projects, 2023-02-01 - * **doc: fix the issue template** - - Andreas Reichel, 2023-02-01 - * **feat: CREATE VIEW ... REFRESH AUTO...** - - Andreas Reichel, 2023-01-30 - * **style: Appease PMD/Codacy** - - Andreas Reichel, 2023-01-29 - * **feat: Oracle Alternative Quoting** - - Andreas Reichel, 2023-01-29 - * **doc: Better integration of the RR diagrams** - - Andreas Reichel, 2023-01-21 - * **feat: make important Classes Serializable** - - Andreas Reichel, 2023-01-21 - * **chore: Make Serializable** - - Andreas Reichel, 2023-01-21 - * **doc: request for `Conventional Commit` messages** - - Andreas Reichel, 2023-01-21 - * **Sphinx Documentation** - - Andreas Reichel, 2023-01-21 - * **Define Reserved Keywords explicitly** - - Andreas Reichel, 2023-01-21 - * **Adjust Gradle to JUnit 5** - - Andreas Reichel, 2023-01-21 - * **Enhanced Keywords** - - Andreas Reichel, 2023-01-21 - * **Remove unused imports** - - Andreas Reichel, 2023-01-21 - * **Fix test resources** - - Andreas Reichel, 2023-01-21 - * **Do not mark SpeedTest for concurrent execution** - - Andreas Reichel, 2023-01-21 - * **Fix incorrect tests** - - Andreas Reichel, 2023-01-21 - * **Remove unused imports** - - Andreas Reichel, 2023-01-21 - * **Adjust Gradle to JUnit 5** - - Andreas Reichel, 2023-01-21 - * **Do not mark SpeedTest for concurrent execution** - - Andreas Reichel, 2023-01-21 - * **Reduce cyclomatic complexity in CreateView.toString** - - zaza, 2023-01-08 - * **Fixes #1684: Support CREATE MATERIALIZED VIEW with AUTO REFRESH** - - zaza, 2022-12-11 - -Version jsqlparser-4.6 -============================================================= - - - * **[maven-release-plugin] prepare release jsqlparser-4.6** - - Tobias Warneke, 2023-02-23 - * **actualized release plugin** - - Tobias Warneke, 2023-02-23 - * **actualized release plugin** - - Tobias Warneke, 2023-02-23 - * **Update build.gradle** - - Tobias, 2023-02-17 - * **Update README.md** - - Tobias, 2023-02-17 - * **Oracle Alternative Quoting (#1722)** - - manticore-projects, 2023-02-07 - * **Issue1673 case within brackets (#1675)** - - manticore-projects, 2023-01-31 - * **Added support for SHOW INDEX from table (#1704)** - - Jayant Kumar Yadav, 2023-01-31 - * **Sphinx Website (#1624)** - - manticore-projects, 2023-01-20 - * **Assorted Fixes #5 (#1715)** - - manticore-projects, 2023-01-20 - * **Support DROP MATERIALIZED VIEW statements (#1711)** - - Tomasz Zarna, 2023-01-12 - * **corrected readme** - - Tobias Warneke, 2023-01-04 - * **Update README.md** - - Tobias, 2022-12-27 - * **Fix #1686: add support for creating views with "IF NOT EXISTS" clause (#1690)** - - Tomasz Zarna, 2022-12-22 - * **Assorted Fixes #4 (#1676)** - - manticore-projects, 2022-12-22 - * **Fixed download war script in the renderRR task (#1659)** - - haha1903, 2022-12-10 - * **Assorted fixes (#1666)** - - manticore-projects, 2022-11-20 - * **Fix parsing statements with multidimensional array PR2 (#1665)** - - manticore-projects, 2022-11-20 - * **removed disabled from Keyword tests and imports** - - Tobias Warneke, 2022-11-02 - * **removed disabled from Keyword tests** - - Tobias Warneke, 2022-11-02 - * **Keywords2: Update whitelisted Keywords (#1653)** - - manticore-projects, 2022-11-02 - * **Enhanced Keywords (#1382)** - - manticore-projects, 2022-10-25 - * **#1610 Support for SKIP LOCKED tokens on SELECT statements (#1649)** - - Lucas Dillmann, 2022-10-25 - * **Assorted fixes (#1646)** - - manticore-projects, 2022-10-16 - * **actualized multiple dependencies** - - Tobias Warneke, 2022-09-28 - * **Bump h2 from 1.4.200 to 2.1.210 (#1639)** - - dependabot[bot], 2022-09-28 - * **Support BigQuery SAFE_CAST (#1622) (#1634)** - - dequn, 2022-09-20 - * **fix: add missing public Getter (#1632)** - - manticore-projects, 2022-09-20 - * **Support timestamptz dateliteral (#1621)** - - Todd Pollak, 2022-08-31 - * **fixes #1617** - - Tobias Warneke, 2022-08-31 - * **fixes #419** - - Tobias Warneke, 2022-08-31 - * **Closes #1604, added simple OVERLAPS support (#1611)** - - Rob Audenaerde, 2022-08-16 - * **Fixes PR #1524 support hive alter sql (#1609)** - - manticore-projects, 2022-08-14 - * **#1524 support hive alter sql : ALTER TABLE name ADD COLUMNS (col_spec[, col_spec ...]) (#1605)** - - Zhumin-lv-wn, 2022-08-03 - * **fixes #1581** - - Tobias Warneke, 2022-07-25 - * **Using own Feature - constant for "delete with returning" #1597 (#1598)** - - gitmotte, 2022-07-25 - * **[maven-release-plugin] prepare for next development iteration** - - Tobias Warneke, 2022-07-22 - -Version jsqlparser-4.5 -============================================================= - - - * **[maven-release-plugin] prepare release jsqlparser-4.5** - - Tobias Warneke, 2022-07-22 - * **introduced changelog generator** - - Tobias Warneke, 2022-07-22 - * **fixes #1596** - - Tobias Warneke, 2022-07-22 - * **integrated test for #1595** - - Tobias Warneke, 2022-07-19 - * **reduced time to parse exception to minimize impact on building time** - - Tobias Warneke, 2022-07-19 - * **add support for drop column if exists (#1594)** - - rrrship, 2022-07-19 - * **PostgreSQL INSERT ... ON CONFLICT Issue #1551 (#1552)** - - manticore-projects, 2022-07-19 - * **Configurable Parser Timeout via Feature (#1592)** - - manticore-projects, 2022-07-19 - * **fixes #1590** - - Tobias Warneke, 2022-07-19 - * **fixes #1590** - - Tobias Warneke, 2022-07-19 - * **extended support Postgres' `Extract( field FROM source)` where `field` is a String instead of a Keyword (#1591)** - - manticore-projects, 2022-07-19 - * **Closes #1579. Added ANALYZE support. (#1587)** - - Rob Audenaerde, 2022-07-14 - * **Closes #1583:: Implement Postgresql optional TABLE in TRUNCATE (#1585)** - - Rob Audenaerde, 2022-07-14 - * **Support table option character set and index options (#1586)** - - luofei, 2022-07-14 - * **corrected a last minute bug** - - Tobias Warneke, 2022-07-09 - * **corrected a last minute bug** - - Tobias Warneke, 2022-07-09 - * **corrected a last minute bug** - - Tobias Warneke, 2022-07-09 - * **fixes #1576** - - Tobias Warneke, 2022-07-09 - * **added simple test for #1580** - - Tobias Warneke, 2022-07-07 - * **disabled test for large cnf expansion and stack overflow problem** - - Tobias Warneke, 2022-07-07 - * **Add test for LikeExpression.setEscape and LikeExpression.getStringExpression (#1568)** - - Caro, 2022-07-07 - * **add support for postgres drop function statement (#1557)** - - rrrship, 2022-07-06 - * **Add support for Hive dialect GROUPING SETS. (#1539)** - - chenwl, 2022-07-06 - * **fixes #1566** - - Tobias Warneke, 2022-06-28 - * **Postgres NATURAL LEFT/RIGHT joins (#1560)** - - manticore-projects, 2022-06-28 - * **compound statement tests (#1545)** - - Matthew Rathbone, 2022-06-08 - * **Allow isolation keywords as column name and aliases (#1534)** - - Tomer Shay (Shimshi), 2022-05-19 - * **added github action badge** - - Tobias, 2022-05-16 - * **Create maven.yml** - - Tobias, 2022-05-16 - * **introduced deparser and toString correction for insert output clause** - - Tobias Warneke, 2022-05-15 - * **revived compilable status after merge** - - Tobias Warneke, 2022-05-15 - * **INSERT with SetOperations (#1531)** - - manticore-projects, 2022-05-15 - * **#1516 rename without column keyword (#1533)** - - manticore-projects, 2022-05-11 - * **Add support for `... ALTER COLUMN ... DROP DEFAULT` (#1532)** - - manticore-projects, 2022-05-11 - * **#1527 DELETE ... RETURNING ... (#1528)** - - manticore-projects, 2022-05-11 - * **fixs #1520 (#1521)** - - chiangcho, 2022-05-11 - * **Unsupported statement (#1519)** - - manticore-projects, 2022-05-11 - * **fixes #1518** - - Tobias Warneke, 2022-04-26 - * **Update bug_report.md (#1512)** - - manticore-projects, 2022-04-22 - * **changed to allow #1481** - - Tobias Warneke, 2022-04-22 - * **Performance Improvements (#1439)** - - manticore-projects, 2022-04-14 - * **[maven-release-plugin] prepare for next development iteration** - - Tobias Warneke, 2022-04-10 - -Version jsqlparser-4.4 -============================================================= - - - * **[maven-release-plugin] prepare release jsqlparser-4.4** - - Tobias Warneke, 2022-04-10 - * **Json function Improvements (#1506)** - - manticore-projects, 2022-04-09 - * **fixes #1505** - - Tobias Warneke, 2022-04-09 - * **fixes #1502** - - Tobias Warneke, 2022-04-09 - * **Issue1500 - Circular References in `AllColumns` and `AllTableColumns` (#1501)** - - manticore-projects, 2022-04-03 - * **Optimize assertCanBeParsedAndDeparsed (#1389)** - - manticore-projects, 2022-04-02 - * **Add geometry distance operator (#1493)** - - Thomas Powell, 2022-04-02 - * **Support WITH TIES option in TOP #1435 (#1479)** - - Olivier Cavadenti, 2022-04-02 - * **https://github.com/JSQLParser/JSqlParser/issues/1483 (#1485)** - - gitmotte, 2022-04-02 - * **fixes #1482** - - Tobias Warneke, 2022-03-15 - * **fixes #1482** - - Tobias Warneke, 2022-03-15 - * **Extending CaseExpression, covering #1458 (#1459)** - - Mathieu Goeminne, 2022-03-15 - * **fixes #1471** - - Tobias Warneke, 2022-02-18 - * **fixes #1471** - - Tobias Warneke, 2022-02-18 - * **fixes #1470** - - Tobias Warneke, 2022-02-06 - * **Add support for IS DISTINCT FROM clause (#1457)** - - Tomer Shay (Shimshi), 2022-01-18 - * **fix fetch present in the end of union query (#1456)** - - chiangcho, 2022-01-18 - * **added SQL_CACHE implementation and changed** - - Tobias Warneke, 2022-01-09 - * **support for db2 with ru (#1446)** - - chiangcho, 2021-12-20 - * **[maven-release-plugin] prepare for next development iteration** - - Tobias Warneke, 2021-12-12 - -Version jsqlparser-4.3 -============================================================= - - - * **[maven-release-plugin] prepare release jsqlparser-4.3** - - Tobias Warneke, 2021-12-12 - * **updated readme.md to show all changes for version 4.3** - - Tobias Warneke, 2021-12-12 - * **Adjust Gradle to JUnit 5 (#1428)** - - manticore-projects, 2021-11-28 - * **corrected some maven plugin versions** - - Tobias Warneke, 2021-11-28 - * **fixes #1429** - - Tobias Warneke, 2021-11-23 - * **closes #1427** - - Tobias Warneke, 2021-11-21 - * **CreateTableTest** - - Tobias Warneke, 2021-11-21 - * **Support EMIT CHANGES for KSQL (#1426)** - - Olivier Cavadenti, 2021-11-21 - * **SelectTest.testMultiPartColumnNameWithDatabaseNameAndSchemaName** - - Tobias Warneke, 2021-11-21 - * **reformatted test source code** - - Tobias Warneke, 2021-11-21 - * **organize imports** - - Tobias Warneke, 2021-11-21 - * **replaced all junit 3 and 4 with junit 5 stuff** - - Tobias Warneke, 2021-11-21 - * **Support RESTART without value (#1425)** - - Olivier Cavadenti, 2021-11-20 - * **Add support for oracle UnPivot when use multi columns at once. (#1419)** - - LeiJun, 2021-11-19 - * **Fix issue in parsing TRY_CAST() function (#1391)** - - Prashant Sutar, 2021-11-19 - * **fixes #1414** - - Tobias Warneke, 2021-11-19 - * **Add support for expressions (such as columns) in AT TIME ZONE expressions (#1413)** - - Tomer Shay (Shimshi), 2021-11-19 - * **Add supported for quoted cast expressions for PostgreSQL (#1411)** - - Tomer Shay (Shimshi), 2021-11-19 - * **added USE SCHEMA and CREATE OR REPLACE
support; things that are allowed in Snowflake SQL (#1409)** - - Richard Kooijman, 2021-11-19 - * **Issue #420 Like Expression with Escape Expression (#1406)** - - manticore-projects, 2021-11-19 - * **fixes #1405 and some junit.jupiter stuff** - - Tobias Warneke, 2021-11-19 - * **#1401 add junit-jupiter-api (#1403)** - - gitmotte, 2021-11-19 - * **Support Postgres Dollar Quotes #1372 (#1395)** - - Olivier Cavadenti, 2021-11-19 - * **Add Delete / Update modifiers for MySQL #1254 (#1396)** - - Olivier Cavadenti, 2021-11-19 - * **Fixes #1381 (#1383)** - - manticore-projects, 2021-11-19 - * **Allows CASE ... ELSE ComplexExpression (#1388)** - - manticore-projects, 2021-11-02 - * **IN() with complex expressions (#1384)** - - manticore-projects, 2021-11-01 - * **Fixes #1385 and PR#1380 (#1386)** - - manticore-projects, 2021-10-22 - * **Fixes #1369 (#1370)** - - Ben Grabham, 2021-10-20 - * **Fixes #1371 (#1377)** - - manticore-projects, 2021-10-20 - * **LIMIT OFFSET with Expressions (#1378)** - - manticore-projects, 2021-10-20 - * **Oracle Multi Column Drop (#1379)** - - manticore-projects, 2021-10-20 - * **Support alias for UnPivot statement (see discussion #1374) (#1380)** - - fabriziodelfranco, 2021-10-20 - * **Issue1352 (#1353)** - - manticore-projects, 2021-10-09 - * **Enhance ALTER TABLE ... DROP CONSTRAINTS ... (#1351)** - - manticore-projects, 2021-10-08 - * **Function to use AllColumns or AllTableColumns Expression (#1350)** - - manticore-projects, 2021-10-08 - * **Postgres compliant ALTER TABLE ... RENAME TO ... (#1334)** - - manticore-projects, 2021-09-18 - * **Postgres compliant ALTER TABLE ... RENAME TO ... (#1334)** - - manticore-projects, 2021-09-18 - * **corrected readme to the new snapshot version** - - Tobias Warneke, 2021-09-08 - * **[maven-release-plugin] prepare for next development iteration** - - Tobias Warneke, 2021-09-08 - -Version jsqlparser-4.2 -============================================================= - - - * **[maven-release-plugin] prepare release jsqlparser-4.2** - - Tobias Warneke, 2021-09-08 - * **introducing test for issue #1328** - - Tobias Warneke, 2021-09-07 - * **included some distinct check** - - Tobias Warneke, 2021-09-07 - * **corrected a merge bug** - - Tobias Warneke, 2021-09-07 - * **Prepare4.2 (#1329)** - - manticore-projects, 2021-09-07 - * **CREATE TABLE AS (...) UNION (...) fails (#1309)** - - François Sécherre, 2021-09-07 - * **Fixes #1325 (#1327)** - - manticore-projects, 2021-09-06 - * **Implement Joins with multiple trailing ON Expressions (#1303)** - - manticore-projects, 2021-09-06 - * **Fix Gradle PMD and Checkstyle (#1318)** - - manticore-projects, 2021-09-01 - * **Fixes #1306 (#1311)** - - manticore-projects, 2021-08-28 - * **Update sets (#1317)** - - manticore-projects, 2021-08-27 - * **Special oracle tests (#1279)** - - manticore-projects, 2021-08-09 - * **Implements Hierarchical CONNECT_BY_ROOT Operator (#1282)** - - manticore-projects, 2021-08-09 - * **Implement Transact-SQL IF ELSE Statement Control Flows. (#1275)** - - manticore-projects, 2021-08-09 - * **Add some flexibility to the Alter Statement (#1293)** - - manticore-projects, 2021-08-02 - * **Implement Oracle's Alter System (#1288)** - - manticore-projects, 2021-08-02 - * **Implement Oracle Named Function Parameters Func( param1 => arg1, ...) (#1283)** - - manticore-projects, 2021-08-02 - * **Implement Gradle Buildsystem (#1271)** - - manticore-projects, 2021-08-02 - * **fixes #1272** - - Tobias Warneke, 2021-07-26 - * **Allowes JdbcParameter or JdbcNamedParameter for MySQL FullTextSearch (#1278)** - - manticore-projects, 2021-07-26 - * **Fixes #1267 Cast into RowConstructor (#1274)** - - manticore-projects, 2021-07-26 - * **Separate MySQL Special String Functions accepting Named Argument Separation as this could collide with ComplexExpressionList when InExpression is involved (#1285)** - - manticore-projects, 2021-07-26 - * **Implements Oracle RENAME oldTable TO newTable Statement (#1286)** - - manticore-projects, 2021-07-26 - * **Implement Oracle Purge Statement (#1287)** - - manticore-projects, 2021-07-26 - * **included jacoco to allow code coverage for netbeans** - - Tobias Warneke, 2021-07-18 - * **corrected a Lookahead problem** - - Tobias Warneke, 2021-07-16 - * **Json functions (#1263)** - - manticore-projects, 2021-07-16 - * **fixes #1255** - - Tobias Warneke, 2021-07-16 - * **Active JJDoc and let it create the Grammar BNF documentation (#1256)** - - manticore-projects, 2021-07-16 - * **Bump commons-io from 2.6 to 2.7 (#1265)** - - dependabot[bot], 2021-07-14 - * **Update README.md** - - Tobias, 2021-07-13 - * **Implement DB2 Special Register Date Time CURRENT DATE and CURRENT TIME (#1252)** - - manticore-projects, 2021-07-13 - * **Rename the PMD ruleset configuration file hoping for automatic synchronization with Codacy (#1251)** - - manticore-projects, 2021-07-13 - * **corrected .travis.yml** - - Tobias Warneke, 2021-07-05 - * **corrected .travis.yml** - - Tobias Warneke, 2021-07-05 - * **Update README.md** - - Tobias, 2021-07-05 - * **fixes #1250** - - Tobias Warneke, 2021-07-01 - * **[maven-release-plugin] prepare for next development iteration** - - Tobias Warneke, 2021-06-30 - -Version jsqlparser-4.1 -============================================================= - - - * **[maven-release-plugin] prepare release jsqlparser-4.1** - - Tobias Warneke, 2021-06-30 - * **fixes #1140** - - Tobias Warneke, 2021-06-30 - * **introduced #1248 halfway** - - Tobias Warneke, 2021-06-30 - * **Savepoint rollback (#1236)** - - manticore-projects, 2021-06-30 - * **Fixes Function Parameter List Brackets issue #1239 (#1240)** - - manticore-projects, 2021-06-30 - * **corrected javadoc problem** - - Tobias Warneke, 2021-06-27 - * **corrected some lookahead problem** - - Tobias Warneke, 2021-06-26 - * **RESET statement, SET PostgreSQL compatibility (#1104)** - - Роман Зотов, 2021-06-26 - * **corrected some lookahead problem** - - Tobias Warneke, 2021-06-26 - * **Implement Oracle Alter Session Statements (#1234)** - - manticore-projects, 2021-06-26 - * **fixes #1230** - - Tobias Warneke, 2021-06-26 - * **Support DELETE FROM T1 USING T2 WHERE ... (#1228)** - - francois-secherre, 2021-06-16 - * **Row access support (#1181)** - - Роман Зотов, 2021-06-16 - * **corrected lookahead problem of PR #1225** - - Tobias Warneke, 2021-06-14 - * **Delete queries without from, with a schema identifier fails (#1224)** - - François Sécherre, 2021-06-14 - * **Create temporary table t(c1, c2) as select ... (#1225)** - - francois-secherre, 2021-06-14 - * **Nested with items (#1221)** - - manticore-projects, 2021-06-10 - * **Implement GROUP BY () without columns (#1218)** - - manticore-projects, 2021-06-03 - * **TSQL Compliant NEXT VALUE FOR sequence_id (but keeping the spurious NEXTVAL FOR expression) (#1216)** - - manticore-projects, 2021-06-02 - * **Pmd clean up (#1215)** - - manticore-projects, 2021-06-02 - * **Add support for boolean 'XOR' operator (#1193)** - - Adaptive Recognition, 2021-06-02 - * **Update README.md** - - Tobias, 2021-05-31 - * **Implement WITH for DELETE, UPDATE and MERGE statements (#1217)** - - manticore-projects, 2021-05-31 - * **increases complex scanning range** - - Tobias Warneke, 2021-05-26 - * **Allow Complex Parsing of Functions (#1200)** - - manticore-projects, 2021-05-26 - * **Add support for AT TIME ZONE expressions (#1196)** - - Tomer Shay (Shimshi), 2021-05-25 - * **fixes #1211** - - Tobias Warneke, 2021-05-25 - * **fixes #1212** - - Tobias Warneke, 2021-05-25 - * **Fix Nested CASE WHEN performance, fixes issue #1162 (#1208)** - - manticore-projects, 2021-05-25 - * **Add support for casts in json expressions (#1189)** - - Tomer Shay (Shimshi), 2021-05-10 - * **fixes #1185** - - Tobias Warneke, 2021-05-04 - * **supporting/fixing unique inside sql function such as count eg - SELECT count(UNIQUE col2) FROM mytable (#1184)** - - RajaSudharsan Adhikesavan, 2021-05-01 - * **Oracle compliant ALTER TABLE ADD/MODIFY deparser (#1163)** - - manticore-projects, 2021-04-21 - * **Pmd (#1165)** - - manticore-projects, 2021-04-20 - * **function order by support (#1108)** - - Роман Зотов, 2021-04-20 - * **fixes #1159** - - Tobias Warneke, 2021-04-16 - * **added improvements of pr to readme** - - Tobias Warneke, 2021-04-16 - * **Assorted fixes to the Java CC Parser definition (#1153)** - - manticore-projects, 2021-04-16 - * **fixes #1138** - - Tobias Warneke, 2021-04-10 - * **fixes #1138** - - Tobias Warneke, 2021-04-10 - * **fixes #1137** - - Tobias Warneke, 2021-04-10 - * **fixes #1136** - - Tobias Warneke, 2021-04-10 - * **issue #1134 adressed** - - Tobias Warneke, 2021-03-20 - * **Add support for union_with_brackets_and_orderby (#1131)** - - Tomer Shay (Shimshi), 2021-03-14 - * **Add support for union without brackets and with limit (#1132)** - - Tomer Shay (Shimshi), 2021-03-14 - * **Add support for functions in an interval expression (#1099)** - - Tomer Shay (Shimshi), 2021-03-14 - * **subArray support arr[1:3] (#1109)** - - Роман Зотов, 2021-02-05 - * **bug fix (#769)** - - Kunal jha, 2021-02-05 - * **Array contructor support (#1105)** - - Роман Зотов, 2021-02-04 - * **Partial support construct tuple as simple expression (#1107)** - - Роман Зотов, 2021-01-31 - * **support create table parameters without columns, parameter values any names (#1106)** - - Роман Зотов, 2021-01-31 - * **fixes #995** - - Tobias Warneke, 2021-01-13 - * **fixes #1100** - - Tobias Warneke, 2021-01-13 - * **next correction of parenthesis around unions** - - Tobias Warneke, 2021-01-11 - * **fixes #992** - - Tobias Warneke, 2021-01-07 - * **corrected patch for case as table name** - - Tobias Warneke, 2021-01-07 - * **Added support for the Case keyword in table names (#1093)** - - Tomer Shay (Shimshi), 2021-01-07 - * **corrected some javadoc parameter** - - Tobias Warneke, 2021-01-03 - * **added missing pivot test files** - - Tobias Warneke, 2021-01-03 - * **fixes #282 - first refactoring to allow with clause as a start in insert and update** - - Tobias Warneke, 2021-01-02 - * **fixes #282 - first refactoring to allow with clause as a start in insert and update** - - Tobias Warneke, 2021-01-02 - * **Update README.md** - - Tobias, 2021-01-02 - * **fixes #887** - - Tobias Warneke, 2021-01-02 - * **fixes #1091 - added H2 casewhen function with conditional parameters** - - Tobias Warneke, 2021-01-01 - * **fixes #1091 - added H2 casewhen function with conditional parameters** - - Tobias Warneke, 2021-01-01 - * **[maven-release-plugin] prepare for next development iteration** - - Tobias Warneke, 2021-01-01 - diff --git a/src/site/sphinx/index.rst b/src/site/sphinx/index.rst index c01f3e1ab..916e4c07b 100644 --- a/src/site/sphinx/index.rst +++ b/src/site/sphinx/index.rst @@ -13,27 +13,42 @@ Java SQL Parser Library usage contribution migration - syntax_stable - syntax_snapshot - javadoc_stable - javadoc_snapshot + SQL Grammar Stable + SQL Grammar Snapshot + Unsupported Grammar + Java API Stable + Java API Snapshot keywords changelog -.. image:: https://maven-badges.herokuapp.com/maven-central/com.github.jsqlparser/jsqlparser/badge.svg - :alt: Maven Repo +.. image:: https://img.shields.io/github/release/JSQLParser/JSqlParser?include_prereleases=&sort=semver&color=blue + :alt: GitGub Release Badge + :target: https://github.com/JSQLParser/JSqlParser/releases + +.. image:: https://img.shields.io/github/issues/JSQLParser/JSqlParser + :alt: GitGub Issues Badge + :target: https://github.com/JSQLParser/JSqlParser/issues + +.. image:: https://badgen.net/maven/v/maven-central/com.github.jsqlparser/jsqlparser + :alt: Maven Badge + :target: https://mvnrepository.com/artifact/com.github.jsqlparser/jsqlparser .. image:: https://github.com/JSQLParser/JSqlParser/actions/workflows/maven.yml/badge.svg :alt: Maven Build Status + :target: https://github.com/JSQLParser/JSqlParser/actions/workflows/maven.yml .. image:: https://coveralls.io/repos/JSQLParser/JSqlParser/badge.svg?branch=master :alt: Coverage Status + :target: https://coveralls.io/github/com.github.jsqlparser/jsqlparser?branch=master .. image:: https://app.codacy.com/project/badge/Grade/6f9a2d7eb98f45969749e101322634a1 :alt: Codacy Status + :target: https://app.codacy.com/gh/com.github.jsqlparser/jsqlparser/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade .. image:: https://www.javadoc.io/badge/com.github.jsqlparser/jsqlparser.svg :alt: Java Docs + :target: https://javadoc.io/doc/com.github.jsqlparser/jsqlparser/latest/index.html + **JSQLParser** is a SQL statement parser built from JavaCC. It translates SQLs in a traversable hierarchy of Java classes. diff --git a/src/site/sphinx/keywords.rst b/src/site/sphinx/keywords.rst index 40778c18d..af0dd839f 100644 --- a/src/site/sphinx/keywords.rst +++ b/src/site/sphinx/keywords.rst @@ -61,6 +61,8 @@ The following Keywords are **restricted** in JSQLParser-|JSQLPARSER_VERSION| and +----------------------+-------------+-----------+ | FULL | Yes | Yes | +----------------------+-------------+-----------+ +| GLOBAL | Yes | | ++----------------------+-------------+-----------+ | GROUP | Yes | Yes | +----------------------+-------------+-----------+ | GROUPING | Yes | | @@ -233,7 +235,7 @@ The following Keywords are **restricted** in JSQLParser-|JSQLPARSER_VERSION| and +----------------------+-------------+-----------+ | OVERLAY | Yes | Yes | +----------------------+-------------+-----------+ -| NEXTVAL | Yes | Yes | +| NEXTVAL | Yes | | +----------------------+-------------+-----------+ | 0x | Yes | Yes | +----------------------+-------------+-----------+ diff --git a/src/site/sphinx/migration.rst b/src/site/sphinx/migration.rst index 6a1fbc9e4..7fc503699 100644 --- a/src/site/sphinx/migration.rst +++ b/src/site/sphinx/migration.rst @@ -1,8 +1,8 @@ ********************************* -Migration to 5.0 +Migration to 4.7 ********************************* -The new version of JSQLParser 5.0 is a rewrite in order to simply accessing the SQL's Abstract Syntax Tree (AST). Quite a few redundant classes have been removed or merged. +The new version of JSQLParser 4.7 is a rewrite in order to simplify accessing the SQL's Abstract Syntax Tree (AST). Quite a few redundant classes have been removed or merged. As always, such a major improvement comes at a certain cost, which is breaking the previous API. Following the guidance below, the new API can be adopted easily although you are welcome to lodge a support request when any questions or concerns arise. @@ -118,7 +118,7 @@ The ``ValuesStatement`` has been replaced by ``Values``, which implements ``Sele `Expression` Lists --------------------------------- -The class ``ExpressionList`` directly extends ``List`` directly and so ``ExpressionList.getExpressions()`` is obsolete. +The class ``ExpressionList`` extends ``List`` directly and so ``ExpressionList.getExpressions()`` is obsolete. Any instance of `List` is considered an Anti Pattern and the class ``ExpressionList`` shall be used instead. @@ -194,11 +194,11 @@ The class ``SelectItem`` is now generic and various deriva `Select` Statement --------------------------------- -``SelectBody`` has been removed and `PlainSelect` can be used directly +``SelectBody`` has been removed and ``PlainSelect`` can be used directly -``SubJoin`` has been replaced by `ParenthesedFromItem`` (implementing a ``FromItem`` with a regular list of ``Join``) +``SubJoin`` has been replaced by ``ParenthesedFromItem`` (implementing a ``FromItem`` with a regular list of ``Join``) -``SubSelect`` has been removed and any instance of ``Select`` (`PlainSelect`, `Values` or `SetOperationList`) can be used instead +``SubSelect`` has been removed and any instance of ``Select`` (``PlainSelect``, ``Values`` or ``SetOperationList``) can be used instead .. tab:: Select @@ -383,5 +383,5 @@ A ``List`` is used for any `Set` clause within `Insert`, `Update`, `U `Statements` collection --------------------------------- -The ``Statements`` class extends `List` directly and so ``Statements.getStatements()`` is obsolete. +The ``Statements`` class extends `List` directly and so `Statements.getStatements()` is obsolete. diff --git a/src/site/sphinx/syntax_stable.rst b/src/site/sphinx/syntax_stable.rst deleted file mode 100644 index 8ea321548..000000000 --- a/src/site/sphinx/syntax_stable.rst +++ /dev/null @@ -1,13867 +0,0 @@ - -********************************************************************* -SQL Syntax |JSQLPARSER_VERSION| Release -********************************************************************* - -The EBNF and Railroad Diagrams for JSQLParser-|JSQLPARSER_VERSION|. - - -====================================================================================================================== -Statement -====================================================================================================================== - - -.. raw:: html - - - - - - IF - - Condition - - SingleStatement - - Block - - ST_SEMICOLON - ELSE - - SingleStatement - - Block - - ST_SEMICOLON - - EOF - - UnsupportedStatement - -
- - -
         ::= ( 'IF' Condition ( ( SingleStatement | Block ) ST_SEMICOLON? 'ELSE' )? )? ( SingleStatement | Block ) ST_SEMICOLON? EOF
-
           | UnsupportedStatement
-
- Not referenced by any. -
- - -====================================================================================================================== -SingleStatement -====================================================================================================================== - - -.. raw:: html - - - - - - WithList - - SelectWithWithItems - - Insert - - Update - - Delete - - Merge - - Select - - Upsert - - Alter - - RenameTableStatement - - Create - - Drop - - Analyze - - Truncate - - Execute - - Set - - Reset - - Show - - Use - - SavepointStatement - - RollbackStatement - COMMIT - - Comment - - Describe - - Explain - - Declare - - Grant - - PurgeStatement - -
- - -
         ::= WithList? ( SelectWithWithItems | Insert | Update | Delete | Merge )
-
           | Select
-
           | Upsert
-
           | Alter
-
           | RenameTableStatement
-
           | Create
-
           | Drop
-
           | Analyze
-
           | Truncate
-
           | Execute
-
           | Set
-
           | Reset
-
           | Show
-
           | Use
-
           | SavepointStatement
-
           | RollbackStatement
-
           | 'COMMIT'
-
           | Comment
-
           | Describe
-
           | Explain
-
           | Declare
-
           | Grant
-
           | PurgeStatement
-
- Referenced by: -
- - -====================================================================================================================== -Block -====================================================================================================================== - - -.. raw:: html - - - - - - BEGIN - - ST_SEMICOLON - - SingleStatement - - Block - - ST_SEMICOLON - END - - ST_SEMICOLON - -
- -
Block    ::= 'BEGIN' ST_SEMICOLON* ( ( SingleStatement | Block ) ST_SEMICOLON )+ 'END' ST_SEMICOLON?
-
- Referenced by: -
- - -====================================================================================================================== -Statements -====================================================================================================================== - - -.. raw:: html - - - - - - ST_SEMICOLON - IF - - Condition - - SingleStatement - - Block - - ST_SEMICOLON - ELSE - - SingleStatement - - Block - - SingleStatement - - Block - - ST_SEMICOLON - - UnsupportedStatement - - ST_SEMICOLON - IF - - Condition - - SingleStatement - - Block - - ST_SEMICOLON - ELSE - - SingleStatement - - Block - - SingleStatement - - Block - - ST_SEMICOLON - - UnsupportedStatement - - EOF - -
- - - -
- Not referenced by any. -
- - -====================================================================================================================== -Declare -====================================================================================================================== - - -.. raw:: html - - - - - - DECLARE - - UserVariable - TABLE - - ( - - ColumnDefinition - , - - ) - - AS - - RelObjectName - - ColDataType - = - - Expression - - UserVariable - , - - -
- -
Declare  ::= 'DECLARE' UserVariable ( 'TABLE' '(' ColumnDefinition ( ',' ColumnDefinition )* ')' | 'AS' RelObjectName | ColDataType ( '=' Expression )? ( ',' UserVariable ColDataType ( '=' Expression )? )* )
-
- Referenced by: -
- - -====================================================================================================================== -Set -====================================================================================================================== - - -.. raw:: html - - - - - - SET - - LOCAL - - SESSION - - K_DATETIMELITERAL - ZONE - - UserVariable - - IdentifierChain - = - - Expression - ZONE - - K_DATETIMELITERAL - = - - RelObjectNameExt - , - - -
- -
Set      ::= 'SET' ( 'LOCAL' | 'SESSION' )? ( K_DATETIMELITERAL 'ZONE' | ( UserVariable | IdentifierChain ) '='? ) Expression ( ',' ( K_DATETIMELITERAL 'ZONE' | RelObjectNameExt '='? )? Expression )*
-
- Referenced by: -
- - -====================================================================================================================== -Reset -====================================================================================================================== - - -.. raw:: html - - - - - - RESET - - K_DATETIMELITERAL - ZONE - - RelObjectName - ALL - - -
- -
Reset    ::= 'RESET' ( K_DATETIMELITERAL 'ZONE' | RelObjectName | 'ALL' )
-
- Referenced by: -
- - -====================================================================================================================== -RenameTableStatement -====================================================================================================================== - - -.. raw:: html - - - - - - RENAME - - TABLE - - IF - - EXISTS - - Table - WAIT - - S_LONG - NOWAIT - - TO - - Table - - Table - , - - -
- - -
         ::= 'RENAME' 'TABLE'? ( 'IF' 'EXISTS' )? Table ( 'WAIT' S_LONG | 'NOWAIT' )? 'TO' Table ( ',' Table 'TO' Table )*
-
- Referenced by: -
- - -====================================================================================================================== -PurgeStatement -====================================================================================================================== - - -.. raw:: html - - - - - - PURGE - - TABLE - - Table - INDEX - - Index - RECYCLEBIN - - DBA_RECYCLEBIN - - TABLESPACE - - S_IDENTIFIER - USER - - S_IDENTIFIER - -
- - -
         ::= 'PURGE' ( 'TABLE' Table | 'INDEX' Index | 'RECYCLEBIN' | 'DBA_RECYCLEBIN' | 'TABLESPACE' S_IDENTIFIER ( 'USER' S_IDENTIFIER )? )
-
- Referenced by: -
- - -====================================================================================================================== -Describe -====================================================================================================================== - - -.. raw:: html - - - - - - DESCRIBE - - Table - -
- -
Describe ::= 'DESCRIBE' Table
-
- Referenced by: -
- - -====================================================================================================================== -Explain -====================================================================================================================== - - -.. raw:: html - - - - - - EXPLAIN - - ExplainStatementOptions - - Select - -
- - -
- Referenced by: -
- - -====================================================================================================================== -ExplainOptionBoolean -====================================================================================================================== - - -.. raw:: html - - - - - - TRUE - - FALSE - - ON - - OFF - - -
- - -
         ::= ( 'TRUE' | 'FALSE' | 'ON' | 'OFF' )?
-
- Referenced by: -
- - -====================================================================================================================== -ExplainFormatOption -====================================================================================================================== - - -.. raw:: html - - - - - - XML - - JSON - - YAML - - -
- - -
         ::= ( 'XML' | 'JSON' | 'YAML' )?
-
- Referenced by: -
- - -====================================================================================================================== -ExplainStatementOptions -====================================================================================================================== - - -.. raw:: html - - - - - - ANALYZE - - BUFFERS - - COSTS - - VERBOSE - - ExplainOptionBoolean - FORMAT - - ExplainFormatOption - -
- - -
         ::= ( ( 'ANALYZE' | 'BUFFERS' | 'COSTS' | 'VERBOSE' ) ExplainOptionBoolean | 'FORMAT' ExplainFormatOption )*
-
- Referenced by: -
- - -====================================================================================================================== -Use -====================================================================================================================== - - -.. raw:: html - - - - - - USE - - SCHEMA - - RelObjectNameExt - -
- -
Use      ::= 'USE' 'SCHEMA'? RelObjectNameExt
-
- Referenced by: -
- - -====================================================================================================================== -Show -====================================================================================================================== - - -.. raw:: html - - - - - - SHOW - - ShowColumns - - ShowIndex - - ShowTables - - captureRest - -
- -
Show     ::= 'SHOW' ( ShowColumns | ShowIndex | ShowTables | captureRest )
-
- Referenced by: -
- - -====================================================================================================================== -ShowColumns -====================================================================================================================== - - -.. raw:: html - - - - - - COLUMNS - - FROM - - RelObjectNameExt - -
- - -
         ::= 'COLUMNS' 'FROM' RelObjectNameExt
-
- Referenced by: -
- - -====================================================================================================================== -ShowIndex -====================================================================================================================== - - -.. raw:: html - - - - - - INDEX - - FROM - - RelObjectNameExt - -
- - -
         ::= 'INDEX' 'FROM' RelObjectNameExt
-
- Referenced by: -
- - -====================================================================================================================== -ShowTables -====================================================================================================================== - - -.. raw:: html - - - - - - EXTENDED - - FULL - - TABLES - - FROM - - IN - - RelObjectNameExt - LIKE - - SimpleExpression - WHERE - - Expression - -
- - -
         ::= 'EXTENDED'? 'FULL'? 'TABLES' ( ( 'FROM' | 'IN' ) RelObjectNameExt )? ( 'LIKE' SimpleExpression | 'WHERE' Expression )?
-
- Referenced by: -
- - -====================================================================================================================== -Values -====================================================================================================================== - - -.. raw:: html - - - - - - VALUES - - VALUE - - ExpressionList - -
- -
Values   ::= ( 'VALUES' | 'VALUE' ) ExpressionList
-
- Referenced by: -
- - -====================================================================================================================== -ReturningClause -====================================================================================================================== - - -.. raw:: html - - - - - - RETURNING - - RETURN - - SelectItemsList - INTO - - Table - - UserVariable - , - - -
- - -
         ::= ( 'RETURNING' | 'RETURN' ) SelectItemsList ( 'INTO' ( Table | UserVariable ) ( ',' ( Table | UserVariable ) )* )?
-
- Referenced by: -
- - -====================================================================================================================== -Update -====================================================================================================================== - - -.. raw:: html - - - - - - UPDATE - - LOW_PRIORITY - - IGNORE - - TableWithAlias - - JoinsList - SET - - UpdateSets - - OutputClause - FROM - - FromItem - - JoinsList - - WhereClause - - OrderByElements - - PlainLimit - - ReturningClause - -
- - -
- Referenced by: -
- - -====================================================================================================================== -UpdateSets -====================================================================================================================== - - -.. raw:: html - - - - - - Column - = - - Expression - - ParenthesedExpressionList - = - - ParenthesedSelect - - ParenthesedExpressionList - , - - Column - = - - Expression - - ParenthesedExpressionList - = - - ParenthesedSelect - - ParenthesedExpressionList - -
- - - -
- - -====================================================================================================================== -Insert -====================================================================================================================== - - -.. raw:: html - - - - - - INSERT - - LOW_PRIORITY - - DELAYED - - HIGH_PRIORITY - - IGNORE - - INTO - - Table - AS - - RelObjectNameWithoutValue - ( - - ColumnList - ) - - OutputClause - SET - - UpdateSets - - Select - ON - - DUPLICATE - - KEY - - UPDATE - - UpdateSets - ON - - CONFLICT - - InsertConflictTarget - - InsertConflictAction - - ReturningClause - -
- -
Insert   ::= 'INSERT' ( 'LOW_PRIORITY' | 'DELAYED' | 'HIGH_PRIORITY' )? 'IGNORE'? 'INTO'? - Table ( 'AS'? RelObjectNameWithoutValue )? ( '(' ColumnList ')' )? OutputClause? ( 'SET' UpdateSets | Select ) ( 'ON' 'DUPLICATE' 'KEY' 'UPDATE' UpdateSets )? ( 'ON' 'CONFLICT' InsertConflictTarget? InsertConflictAction )? ReturningClause?
-
- Referenced by: -
- - -====================================================================================================================== -InsertConflictTarget -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - RelObjectNameExt2 - , - - ) - - WhereClause - ON - - CONSTRAINT - - RelObjectNameExt2 - -
- - -
         ::= '(' RelObjectNameExt2 ( ',' RelObjectNameExt2 )* ')' WhereClause?
-
           | 'ON' 'CONSTRAINT' RelObjectNameExt2
-
- Referenced by: -
- - -====================================================================================================================== -InsertConflictAction -====================================================================================================================== - - -.. raw:: html - - - - - - DO - - NOTHING - - UPDATE - - SET - - UpdateSets - - WhereClause - -
- - -
         ::= 'DO' ( 'NOTHING' | 'UPDATE' 'SET' UpdateSets WhereClause? )
-
- Referenced by: -
- - -====================================================================================================================== -OutputClause -====================================================================================================================== - - -.. raw:: html - - - - - - OUTPUT - - SelectItemsList - INTO - - UserVariable - - Table - - ColumnsNamesList - -
- - -
         ::= 'OUTPUT' SelectItemsList ( 'INTO' ( UserVariable | Table ) ColumnsNamesList? )?
-
- Referenced by: -
- - -====================================================================================================================== -Upsert -====================================================================================================================== - - -.. raw:: html - - - - - - UPSERT - - INSERT - - OR - - REPLACE - - INTO - - Table - - ParenthesedColumnList - SET - - UpdateSets - - Select - ON - - DUPLICATE - - KEY - - UPDATE - - UpdateSets - -
- -
Upsert   ::= ( 'UPSERT' | ( 'INSERT' 'OR' )? 'REPLACE' ) 'INTO'? Table ParenthesedColumnList? ( 'SET' UpdateSets | Select ) ( 'ON' 'DUPLICATE' 'KEY' 'UPDATE' UpdateSets )?
-
- Referenced by: -
- - -====================================================================================================================== -Delete -====================================================================================================================== - - -.. raw:: html - - - - - - DELETE - - LOW_PRIORITY - - QUICK - - IGNORE - - TableWithAlias - , - - OutputClause - FROM - - TableWithAlias - - JoinsList - USING - - TableWithAlias - , - - WhereClause - - OrderByElements - - PlainLimit - - ReturningClause - -
- -
Delete   ::= 'DELETE' 'LOW_PRIORITY'? 'QUICK'? 'IGNORE'? ( ( TableWithAlias ( ',' TableWithAlias )* OutputClause? )? 'FROM' )? ( TableWithAlias JoinsList? )? ( 'USING' TableWithAlias ( ',' TableWithAlias )* )? WhereClause? OrderByElements? PlainLimit? ReturningClause?
-
- Referenced by: -
- - -====================================================================================================================== -Merge -====================================================================================================================== - - -.. raw:: html - - - - - - MERGE - - INTO - - TableWithAlias - USING - - FromItem - ON - - ( - - Expression - ) - - MergeUpdateClause - - MergeInsertClause - - MergeInsertClause - - MergeUpdateClause - -
- - -
- Referenced by: -
- - -====================================================================================================================== -MergeUpdateClause -====================================================================================================================== - - -.. raw:: html - - - - - - WHEN - - MATCHED - - THEN - - UPDATE - - SET - - UpdateSets - WHERE - - Expression - DELETE - - WHERE - - Expression - -
- - -
         ::= 'WHEN' 'MATCHED' 'THEN' 'UPDATE' 'SET' UpdateSets ( 'WHERE' Expression )? ( 'DELETE' 'WHERE' Expression )?
-
- Referenced by: -
- - -====================================================================================================================== -MergeInsertClause -====================================================================================================================== - - -.. raw:: html - - - - - - WHEN - - NOT - - MATCHED - - THEN - - INSERT - - ( - - ColumnList - ) - - VALUES - - ( - - SimpleExpressionList - ) - - WHERE - - Expression - -
- - -
         ::= 'WHEN' 'NOT' 'MATCHED' 'THEN' 'INSERT' ( '(' ColumnList ')' )? 'VALUES' '(' SimpleExpressionList ')' ( 'WHERE' Expression )?
-
- Referenced by: -
- - -====================================================================================================================== -RelObjectNameList -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameExt - . - - : - - . - - RelObjectNameExt2 - -
- - -
         ::= RelObjectNameExt ( ( '.' | ':' ) '.'* RelObjectNameExt2 )*
-
- - -====================================================================================================================== -Column -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameList - . - - K_NEXTVAL - - ArrayConstructor - -
- - -
- - -====================================================================================================================== -RelObjectNameWithoutValue -====================================================================================================================== - - -.. raw:: html - - - - - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - - K_DATE_LITERAL - - K_DATETIMELITERAL - - K_STRING_FUNCTION_NAME - - K_ISOLATION - - K_TIME_KEY_EXPR - ACTION - - ACTIVE - - ADD - - ADVANCE - - ADVISE - - AGAINST - - ALGORITHM - - ALTER - - ANALYZE - - APPLY - - ARCHIVE - - ARRAY - - ASC - - AT - - AUTHORIZATION - - AUTO - - BEGIN - - BINARY - - BIT - - BUFFERS - - BY - - BYTE - - BYTES - - CACHE - - CALL - - CASCADE - - CASE - - CAST - - CHANGE - - CHANGES - - CHAR - - CHARACTER - - CHECKPOINT - - CLOSE - - COLLATE - - COLUMN - - COLUMNS - - COMMENT - - COMMIT - - CONFLICT - - CONVERT - - COSTS - - CS - - CYCLE - - DATABASE - - DDL - - DECLARE - - DEFAULT - - DEFERRABLE - - DELAYED - - DELETE - - DESC - - DESCRIBE - - DISABLE - - DISCONNECT - - DIV - - DML - - DO - - DOMAIN - - DROP - - DUMP - - DUPLICATE - - EMIT - - ENABLE - - END - - ESCAPE - - EXCLUDE - - EXEC - - EXECUTE - - EXPLAIN - - EXTENDED - - EXTRACT - - FALSE - - FILTER - - FIRST - - FLUSH - - FN - - FOLLOWING - - FORMAT - - FULLTEXT - - FUNCTION - - GLOBAL - - GRANT - - GUARD - - HISTORY - - HOPPING - - INCLUDE - - INCREMENT - - INDEX - - INSERT - - INTERLEAVE - - ISNULL - - JSON - - KEEP - - KEY - - KEYS - - LAST - - LEADING - - LINK - - LOCAL - - LOCKED - - LOG - - MATCH - - MATCHED - - MATERIALIZED - - MAXVALUE - - MEMBER - - MERGE - - MINVALUE - - MODIFY - - MOVEMENT - - NEXT - - NO - - NOCACHE - - NOKEEP - - NOLOCK - - NOMAXVALUE - - NOMINVALUE - - NOORDER - - NOTHING - - NOVALIDATE - - NOWAIT - - NULLS - - OF - - OFF - - OPEN - - OVER - - OVERLAPS - - PARALLEL - - PARENT - - PARTITION - - PATH - - PERCENT - - PLACING - - PRECEDING - - PRECISION - - PRIMARY - - PRIOR - - PURGE - - QUERY - - QUICK - - QUIESCE - - RANGE - - READ - - RECYCLEBIN - - REFERENCES - - REFRESH - - REGISTER - - RENAME - - REPLACE - - RESET - - RESTART - - RESTRICT - - RESTRICTED - - RESUMABLE - - RESUME - - RLIKE - - ROLLBACK - - ROW - - ROWS - - RR - - RS - - SAVEPOINT - - SCHEMA - - SEPARATOR - - SEQUENCE - - SESSION - - SETS - - SHOW - - SHUTDOWN - - SIBLINGS - - SIGNED - - SIMILAR - - SIZE - - SKIP - - STORED - - STRING - - SUSPEND - - SWITCH - - SYNONYM - - SYSTEM - - TABLE - - TABLESPACE - - TEMP - - TEMPORARY - - THEN - - TIMEOUT - - TIMESTAMPTZ - - TO - - TRIGGER - - TRUE - - TRUNCATE - - TUMBLING - - TYPE - - UNLOGGED - - UNQIESCE - - UNSIGNED - - UPDATE - - UPSERT - - UR - - USER - - VALIDATE - - VERBOSE - - VIEW - - WAIT - - WITHIN - - WITHOUT - - WORK - - XML - - XMLAGG - - XMLTEXT - - YAML - - YES - - ZONE - - -
- - -
         ::= S_IDENTIFIER
-
           | S_QUOTED_IDENTIFIER
-
           | K_DATE_LITERAL
-
           | K_DATETIMELITERAL
-
           | K_STRING_FUNCTION_NAME
-
           | K_ISOLATION
-
           | K_TIME_KEY_EXPR
-
           | 'ACTION'
-
           | 'ACTIVE'
-
           | 'ADD'
-
           | 'ADVANCE'
-
           | 'ADVISE'
-
           | 'AGAINST'
-
           | 'ALGORITHM'
-
           | 'ALTER'
-
           | 'ANALYZE'
-
           | 'APPLY'
-
           | 'ARCHIVE'
-
           | 'ARRAY'
-
           | 'ASC'
-
           | 'AT'
-
           | 'AUTHORIZATION'
-
           | 'AUTO'
-
           | 'BEGIN'
-
           | 'BINARY'
-
           | 'BIT'
-
           | 'BUFFERS'
-
           | 'BY'
-
           | 'BYTE'
-
           | 'BYTES'
-
           | 'CACHE'
-
           | 'CALL'
-
           | 'CASCADE'
-
           | 'CASE'
-
           | 'CAST'
-
           | 'CHANGE'
-
           | 'CHANGES'
-
           | 'CHAR'
-
           | 'CHARACTER'
-
           | 'CHECKPOINT'
-
           | 'CLOSE'
-
           | 'COLLATE'
-
           | 'COLUMN'
-
           | 'COLUMNS'
-
           | 'COMMENT'
-
           | 'COMMIT'
-
           | 'CONFLICT'
-
           | 'CONVERT'
-
           | 'COSTS'
-
           | 'CS'
-
           | 'CYCLE'
-
           | 'DATABASE'
-
           | 'DDL'
-
           | 'DECLARE'
-
           | 'DEFAULT'
-
           | 'DEFERRABLE'
-
           | 'DELAYED'
-
           | 'DELETE'
-
           | 'DESC'
-
           | 'DESCRIBE'
-
           | 'DISABLE'
-
           | 'DISCONNECT'
-
           | 'DIV'
-
           | 'DML'
-
           | 'DO'
-
           | 'DOMAIN'
-
           | 'DROP'
-
           | 'DUMP'
-
           | 'DUPLICATE'
-
           | 'EMIT'
-
           | 'ENABLE'
-
           | 'END'
-
           | 'ESCAPE'
-
           | 'EXCLUDE'
-
           | 'EXEC'
-
           | 'EXECUTE'
-
           | 'EXPLAIN'
-
           | 'EXTENDED'
-
           | 'EXTRACT'
-
           | 'FALSE'
-
           | 'FILTER'
-
           | 'FIRST'
-
           | 'FLUSH'
-
           | 'FN'
-
           | 'FOLLOWING'
-
           | 'FORMAT'
-
           | 'FULLTEXT'
-
           | 'FUNCTION'
-
           | 'GLOBAL'
-
           | 'GRANT'
-
           | 'GUARD'
-
           | 'HISTORY'
-
           | 'HOPPING'
-
           | 'INCLUDE'
-
           | 'INCREMENT'
-
           | 'INDEX'
-
           | 'INSERT'
-
           | 'INTERLEAVE'
-
           | 'ISNULL'
-
           | 'JSON'
-
           | 'KEEP'
-
           | 'KEY'
-
           | 'KEYS'
-
           | 'LAST'
-
           | 'LEADING'
-
           | 'LINK'
-
           | 'LOCAL'
-
           | 'LOCKED'
-
           | 'LOG'
-
           | 'MATCH'
-
           | 'MATCHED'
-
           | 'MATERIALIZED'
-
           | 'MAXVALUE'
-
           | 'MEMBER'
-
           | 'MERGE'
-
           | 'MINVALUE'
-
           | 'MODIFY'
-
           | 'MOVEMENT'
-
           | 'NEXT'
-
           | 'NO'
-
           | 'NOCACHE'
-
           | 'NOKEEP'
-
           | 'NOLOCK'
-
           | 'NOMAXVALUE'
-
           | 'NOMINVALUE'
-
           | 'NOORDER'
-
           | 'NOTHING'
-
           | 'NOVALIDATE'
-
           | 'NOWAIT'
-
           | 'NULLS'
-
           | 'OF'
-
           | 'OFF'
-
           | 'OPEN'
-
           | 'OVER'
-
           | 'OVERLAPS'
-
           | 'PARALLEL'
-
           | 'PARENT'
-
           | 'PARTITION'
-
           | 'PATH'
-
           | 'PERCENT'
-
           | 'PLACING'
-
           | 'PRECEDING'
-
           | 'PRECISION'
-
           | 'PRIMARY'
-
           | 'PRIOR'
-
           | 'PURGE'
-
           | 'QUERY'
-
           | 'QUICK'
-
           | 'QUIESCE'
-
           | 'RANGE'
-
           | 'READ'
-
           | 'RECYCLEBIN'
-
           | 'REFERENCES'
-
           | 'REFRESH'
-
           | 'REGISTER'
-
           | 'RENAME'
-
           | 'REPLACE'
-
           | 'RESET'
-
           | 'RESTART'
-
           | 'RESTRICT'
-
           | 'RESTRICTED'
-
           | 'RESUMABLE'
-
           | 'RESUME'
-
           | 'RLIKE'
-
           | 'ROLLBACK'
-
           | 'ROW'
-
           | 'ROWS'
-
           | 'RR'
-
           | 'RS'
-
           | 'SAVEPOINT'
-
           | 'SCHEMA'
-
           | 'SEPARATOR'
-
           | 'SEQUENCE'
-
           | 'SESSION'
-
           | 'SETS'
-
           | 'SHOW'
-
           | 'SHUTDOWN'
-
           | 'SIBLINGS'
-
           | 'SIGNED'
-
           | 'SIMILAR'
-
           | 'SIZE'
-
           | 'SKIP'
-
           | 'STORED'
-
           | 'STRING'
-
           | 'SUSPEND'
-
           | 'SWITCH'
-
           | 'SYNONYM'
-
           | 'SYSTEM'
-
           | 'TABLE'
-
           | 'TABLESPACE'
-
           | 'TEMP'
-
           | 'TEMPORARY'
-
           | 'THEN'
-
           | 'TIMEOUT'
-
           | 'TIMESTAMPTZ'
-
           | 'TO'
-
           | 'TRIGGER'
-
           | 'TRUE'
-
           | 'TRUNCATE'
-
           | 'TUMBLING'
-
           | 'TYPE'
-
           | 'UNLOGGED'
-
           | 'UNQIESCE'
-
           | 'UNSIGNED'
-
           | 'UPDATE'
-
           | 'UPSERT'
-
           | 'UR'
-
           | 'USER'
-
           | 'VALIDATE'
-
           | 'VERBOSE'
-
           | 'VIEW'
-
           | 'WAIT'
-
           | 'WITHIN'
-
           | 'WITHOUT'
-
           | 'WORK'
-
           | 'XML'
-
           | 'XMLAGG'
-
           | 'XMLTEXT'
-
           | 'YAML'
-
           | 'YES'
-
           | 'ZONE'
-
- - -====================================================================================================================== -RelObjectName -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameWithoutValue - GROUP - - INTERVAL - - ON - - START - - TOP - - VALUE - - VALUES - - CREATE - - TABLES - - CONNECT - - IGNORE - - -
- - -
         ::= RelObjectNameWithoutValue
-
           | 'GROUP'
-
           | 'INTERVAL'
-
           | 'ON'
-
           | 'START'
-
           | 'TOP'
-
           | 'VALUE'
-
           | 'VALUES'
-
           | 'CREATE'
-
           | 'TABLES'
-
           | 'CONNECT'
-
           | 'IGNORE'
-
- - -====================================================================================================================== -RelObjectNameWithoutStart -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameWithoutValue - TOP - - VALUE - - VALUES - - INTERVAL - - -
- - -
         ::= RelObjectNameWithoutValue
-
           | 'TOP'
-
           | 'VALUE'
-
           | 'VALUES'
-
           | 'INTERVAL'
-
- Referenced by: -
- - -====================================================================================================================== -RelObjectNameExt -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectName - ALL - - ANY - - SOME - - LEFT - - RIGHT - - SET - - DOUBLE - - IF - - IIF - - OPTIMIZE - - LIMIT - - OFFSET - - PROCEDURE - - PUBLIC - - CASEWHEN - - IN - - GROUPING - - ORDER - - -
- - -
         ::= RelObjectName
-
           | 'ALL'
-
           | 'ANY'
-
           | 'SOME'
-
           | 'LEFT'
-
           | 'RIGHT'
-
           | 'SET'
-
           | 'DOUBLE'
-
           | 'IF'
-
           | 'IIF'
-
           | 'OPTIMIZE'
-
           | 'LIMIT'
-
           | 'OFFSET'
-
           | 'PROCEDURE'
-
           | 'PUBLIC'
-
           | 'CASEWHEN'
-
           | 'IN'
-
           | 'GROUPING'
-
           | 'ORDER'
-
- - -====================================================================================================================== -RelObjectNameExt2 -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameExt - FROM - - K_SELECT - CURRENT - - -
- - -
         ::= RelObjectNameExt
-
           | 'FROM'
-
           | K_SELECT
-
           | 'CURRENT'
-
- - -====================================================================================================================== -Table -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameList - -
- - -
- - -====================================================================================================================== -TableWithAlias -====================================================================================================================== - - -.. raw:: html - - - - - - Table - - Alias - -
- - -
         ::= Table Alias?
-
- Referenced by: -
- - -====================================================================================================================== -SelectWithWithItems -====================================================================================================================== - - -.. raw:: html - - - - - - Select - -
- - -
         ::= Select
-
- Referenced by: -
- - -====================================================================================================================== -Select -====================================================================================================================== - - -.. raw:: html - - - - - - WithList - - PlainSelect - - Values - - ParenthesedSelect - - SetOperationList - - OrderByElements - - LimitWithOffset - - Offset - - Fetch - - WithIsolation - -
- - -
- - -====================================================================================================================== -ParenthesedSelect -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - Select - ) - - -
- - -
         ::= '(' Select ')'
-
- - -====================================================================================================================== -LateralView -====================================================================================================================== - - -.. raw:: html - - - - - - LATERAL - - VIEW - - OUTER - - Function - - RelObjectNameWithoutStart - AS - - RelObjectNameWithoutStart - -
- - -
         ::= 'LATERAL' 'VIEW' 'OUTER'? Function RelObjectNameWithoutStart? 'AS' RelObjectNameWithoutStart
-
- Referenced by: -
- - -====================================================================================================================== -LateralViews -====================================================================================================================== - - -.. raw:: html - - - - - - LateralView - -
- - -
         ::= LateralView+
-
- Referenced by: -
- - -====================================================================================================================== -LateralSubSelect -====================================================================================================================== - - -.. raw:: html - - - - - - LATERAL - - ( - - Select - ) - - -
- - -
         ::= 'LATERAL' '(' Select ')'
-
- Referenced by: -
- - -====================================================================================================================== -PlainSelect -====================================================================================================================== - - -.. raw:: html - - - - - - K_SELECT - STRAIGHT_JOIN - - Skip - - First - ALL - - DISTINCT - - ON - - ( - - SelectItemsList - ) - - UNIQUE - - SQL_CALC_FOUND_ROWS - - SQL_NO_CACHE - - SQL_CACHE - - Top - - SelectItemsList - - IntoClause - FROM - - FromItem - - LateralViews - - JoinsList - FINAL - - KSQLWindowClause - - WhereClause - - OracleHierarchicalQueryClause - - Having - - GroupByColumnReferences - - Having - - OrderByElements - WINDOW - - RelObjectName - AS - - windowDefinition - , - - OrderByElements - EMIT - - CHANGES - - LimitBy - - LimitWithOffset - - Offset - - LimitWithOffset - - Fetch - - WithIsolation - FOR - - UPDATE - - OF - - Table - - Wait - NOWAIT - - SKIP - - LOCKED - - OptimizeFor - FOR - - XML - - PATH - - ( - - S_CHAR_LITERAL - ) - - -
- - -
         ::= K_SELECT 'STRAIGHT_JOIN'? Skip? First? ( 'ALL' | 'DISTINCT' ( 'ON' '(' SelectItemsList ')' )? | 'UNIQUE' | 'SQL_CALC_FOUND_ROWS' | 'SQL_NO_CACHE' | 'SQL_CACHE' )? Top? SelectItemsList IntoClause? ( 'FROM' FromItem LateralViews? JoinsList? )? 'FINAL'? KSQLWindowClause? WhereClause? OracleHierarchicalQueryClause? Having? GroupByColumnReferences? Having? OrderByElements? ( 'WINDOW' RelObjectName 'AS' windowDefinition ( ',' RelObjectName 'AS' windowDefinition )* )? OrderByElements? ( 'EMIT' 'CHANGES' )? LimitBy? LimitWithOffset? Offset? LimitWithOffset? Fetch? WithIsolation? ( 'FOR' 'UPDATE' ( 'OF' Table )? Wait? ( 'NOWAIT' | 'SKIP' 'LOCKED' )? )? OptimizeFor? ( 'FOR' 'XML' 'PATH' '(' S_CHAR_LITERAL ')' )?
-
- Referenced by: -
- - -====================================================================================================================== -SetOperationList -====================================================================================================================== - - -.. raw:: html - - - - - - UNION - - ALL - - DISTINCT - - INTERSECT - - MINUS - - EXCEPT - - PlainSelect - - Values - - ParenthesedSelect - - OrderByElements - - LimitWithOffset - - Offset - - LimitWithOffset - - Fetch - - WithIsolation - -
- - -
         ::= ( ( 'UNION' ( 'ALL' | 'DISTINCT' )? | 'INTERSECT' | 'MINUS' | 'EXCEPT' - ) ( PlainSelect | Values | ParenthesedSelect ) )+ OrderByElements? LimitWithOffset? Offset? LimitWithOffset? Fetch? WithIsolation?
-
- Referenced by: -
- - -====================================================================================================================== -WithList -====================================================================================================================== - - -.. raw:: html - - - - - - WITH - - WithItem - , - - -
- -
WithList ::= 'WITH' WithItem ( ',' WithItem )*
-
- Referenced by: -
- - -====================================================================================================================== -WithItem -====================================================================================================================== - - -.. raw:: html - - - - - - RECURSIVE - - RelObjectName - ( - - SelectItemsList - ) - - AS - - ParenthesedSelect - -
- -
WithItem ::= 'RECURSIVE'? RelObjectName ( '(' SelectItemsList ')' )? 'AS' ParenthesedSelect
-
- Referenced by: -
- - -====================================================================================================================== -SelectItemsList -====================================================================================================================== - - -.. raw:: html - - - - - - SelectItem - , - - -
- - -
         ::= SelectItem ( ',' SelectItem )*
-
- - -====================================================================================================================== -SelectItem -====================================================================================================================== - - -.. raw:: html - - - - - - * - - AllTableColumns - - Condition - - ConcatExpression - - Expression - - Alias - -
- - -
         ::= ( '*' | AllTableColumns | Condition | ConcatExpression | Expression ) Alias?
-
- Referenced by: -
- - -====================================================================================================================== -AllTableColumns -====================================================================================================================== - - -.. raw:: html - - - - - - Table - . - - * - - -
- - -
         ::= Table '.' '*'
-
- Referenced by: -
- - -====================================================================================================================== -Alias -====================================================================================================================== - - -.. raw:: html - - - - - - AS - - RelObjectNameWithoutStart - - S_CHAR_LITERAL - ( - - RelObjectName - - ColDataType - , - - ) - - -
- - -
- - -====================================================================================================================== -SQLServerHint -====================================================================================================================== - - -.. raw:: html - - - - - - INDEX - - ( - - RelObjectName - ) - - NOLOCK - - -
- - -
         ::= 'INDEX' '(' RelObjectName ')'
-
           | 'NOLOCK'
-
- Referenced by: -
- - -====================================================================================================================== -SQLServerHints -====================================================================================================================== - - -.. raw:: html - - - - - - WITH - - ( - - SQLServerHint - , - - ) - - -
- - -
         ::= 'WITH' '(' SQLServerHint ( ',' SQLServerHint )* ')'
-
- Referenced by: -
- - -====================================================================================================================== -MySQLIndexHint -====================================================================================================================== - - -.. raw:: html - - - - - - USE - - SHOW - - IGNORE - - FORCE - - INDEX - - KEY - - ( - - RelObjectNameWithoutValue - , - - ) - - -
- - -
         ::= ( 'USE' | 'SHOW' | 'IGNORE' | 'FORCE' ) ( 'INDEX' | 'KEY' ) '(' RelObjectNameWithoutValue ( ',' RelObjectNameWithoutValue )* ')'
-
- Referenced by: -
- - -====================================================================================================================== -FunctionItem -====================================================================================================================== - - -.. raw:: html - - - - - - Function - - Alias - -
- - -
         ::= Function Alias?
-
- Referenced by: -
- - -====================================================================================================================== -PivotForColumns -====================================================================================================================== - - -.. raw:: html - - - - - - ParenthesedColumnList - - Column - -
- - -
         ::= ParenthesedColumnList
-
           | Column
-
- Referenced by: -
- - -====================================================================================================================== -PivotFunctionItems -====================================================================================================================== - - -.. raw:: html - - - - - - FunctionItem - , - - -
- - -
         ::= FunctionItem ( ',' FunctionItem )*
-
- Referenced by: -
- - -====================================================================================================================== -ExpressionListItem -====================================================================================================================== - - -.. raw:: html - - - - - - ParenthesedExpressionList - - Alias - -
- - -
         ::= ParenthesedExpressionList Alias?
-
- Referenced by: -
- - -====================================================================================================================== -PivotMultiInItems -====================================================================================================================== - - -.. raw:: html - - - - - - ExpressionListItem - , - - -
- - -
         ::= ExpressionListItem ( ',' ExpressionListItem )*
-
- Referenced by: -
- - -====================================================================================================================== -Pivot -====================================================================================================================== - - -.. raw:: html - - - - - - PIVOT - - ( - - PivotFunctionItems - FOR - - PivotForColumns - IN - - ( - - SelectItemsList - - PivotMultiInItems - ) - - ) - - Alias - -
- -
Pivot    ::= 'PIVOT' '(' PivotFunctionItems 'FOR' PivotForColumns 'IN' '(' ( SelectItemsList | PivotMultiInItems ) ')' ')' Alias?
-
- Referenced by: -
- - -====================================================================================================================== -PivotXml -====================================================================================================================== - - -.. raw:: html - - - - - - PIVOT - - XML - - ( - - PivotFunctionItems - FOR - - PivotForColumns - IN - - ( - - ANY - - Select - - SelectItemsList - - PivotMultiInItems - ) - - ) - - -
- -
PivotXml ::= 'PIVOT' 'XML' '(' PivotFunctionItems 'FOR' PivotForColumns 'IN' '(' ( 'ANY' | Select | SelectItemsList | PivotMultiInItems ) ')' ')'
-
- Referenced by: -
- - -====================================================================================================================== -UnPivot -====================================================================================================================== - - -.. raw:: html - - - - - - UNPIVOT - - INCLUDE - - EXCLUDE - - NULLS - - ( - - PivotForColumns - FOR - - PivotForColumns - IN - - ( - - SelectItemsList - ) - - ) - - Alias - -
- -
UnPivot  ::= 'UNPIVOT' ( ( 'INCLUDE' | 'EXCLUDE' ) 'NULLS' )? '(' PivotForColumns 'FOR' PivotForColumns 'IN' '(' SelectItemsList ')' ')' Alias?
-
- Referenced by: -
- - -====================================================================================================================== -IntoClause -====================================================================================================================== - - -.. raw:: html - - - - - - INTO - - Table - , - - -
- - -
         ::= 'INTO' Table ( ',' Table )*
-
- Referenced by: -
- - -====================================================================================================================== -ParenthesedFromItem -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - FromItem - - JoinsList - ) - - -
- - -
         ::= '(' FromItem JoinsList? ')'
-
- Referenced by: -
- - -====================================================================================================================== -FromItem -====================================================================================================================== - - -.. raw:: html - - - - - - TableFunction - - Table - - ParenthesedFromItem - - ParenthesedSelect - - Pivot - - UnPivot - - LateralSubSelect - - Alias - - UnPivot - - PivotXml - - Pivot - - MySQLIndexHint - - SQLServerHints - -
- - -
- - -====================================================================================================================== -JoinsList -====================================================================================================================== - - -.. raw:: html - - - - - - JoinerExpression - -
- - -
         ::= JoinerExpression+
-
- - -====================================================================================================================== -JoinerExpression -====================================================================================================================== - - -.. raw:: html - - - - - - GLOBAL - - NATURAL - - RIGHT - - FULL - - OUTER - - LEFT - - SEMI - - OUTER - - INNER - - CROSS - - JOIN - - , - - OUTER - - STRAIGHT_JOIN - - APPLY - - FromItem - WITHIN - - ( - - JoinWindow - ) - - ON - - Expression - USING - - ( - - Column - , - - ) - - -
- - -
         ::= 'GLOBAL'? 'NATURAL'? ( ( 'RIGHT' | 'FULL' )? 'OUTER'? | 'LEFT' ( 'SEMI' - | 'OUTER' )? | 'INNER' | 'CROSS' ) ( 'JOIN' | ',' 'OUTER'? | 'STRAIGHT_JOIN' | 'APPLY' - ) FromItem ( ( 'WITHIN' '(' JoinWindow ')' )? ( 'ON' Expression )+ | 'USING' '(' Column ( ',' Column )* ')' )?
-
- Referenced by: -
- - -====================================================================================================================== -JoinWindow -====================================================================================================================== - - -.. raw:: html - - - - - - S_LONG - - S_IDENTIFIER - - K_DATE_LITERAL - , - - S_LONG - - S_IDENTIFIER - - K_DATE_LITERAL - -
- - -
         ::= S_LONG ( S_IDENTIFIER | K_DATE_LITERAL ) ( ',' S_LONG ( S_IDENTIFIER | K_DATE_LITERAL ) )?
-
- Referenced by: -
- - -====================================================================================================================== -KSQLWindowClause -====================================================================================================================== - - -.. raw:: html - - - - - - WINDOW - - HOPPING - - ( - - SIZE - - S_LONG - - S_IDENTIFIER - , - - ADVANCE - - BY - - SESSION - - ( - - TUMBLING - - ( - - SIZE - - S_LONG - - S_IDENTIFIER - ) - - -
- - -
         ::= 'WINDOW' ( 'HOPPING' '(' 'SIZE' S_LONG S_IDENTIFIER ',' 'ADVANCE' 'BY' | 'SESSION' '(' | 'TUMBLING' '(' 'SIZE' ) S_LONG S_IDENTIFIER ')'
-
- Referenced by: -
- - -====================================================================================================================== -WhereClause -====================================================================================================================== - - -.. raw:: html - - - - - - WHERE - - Expression - -
- - -
         ::= 'WHERE' Expression
-
- - -====================================================================================================================== -OracleHierarchicalQueryClause -====================================================================================================================== - - -.. raw:: html - - - - - - START - - WITH - - AndExpression - CONNECT - - BY - - NOCYCLE - - CONNECT - - BY - - NOCYCLE - - AndExpression - START - - WITH - - AndExpression - -
- - -
         ::= ( 'START' 'WITH' AndExpression 'CONNECT' 'BY' 'NOCYCLE'? | 'CONNECT' 'BY' 'NOCYCLE'? ( AndExpression 'START' 'WITH' )? ) AndExpression
-
- Referenced by: -
- - -====================================================================================================================== -GroupByColumnReferences -====================================================================================================================== - - -.. raw:: html - - - - - - GROUP - - BY - - GROUPING - - SETS - - ( - - GroupingSet - , - - ) - - ExpressionList - GROUPING - - SETS - - ( - - GroupingSet - , - - ) - - -
- - -
         ::= 'GROUP' 'BY' ( 'GROUPING' 'SETS' '(' GroupingSet ( ',' GroupingSet )* ')' | ExpressionList ( 'GROUPING' 'SETS' '(' GroupingSet ( ',' GroupingSet )* ')' )? )
-
- Referenced by: -
- - -====================================================================================================================== -GroupingSet -====================================================================================================================== - - -.. raw:: html - - - - - - ParenthesedExpressionList - - SimpleExpression - -
- - -
         ::= ParenthesedExpressionList
-
           | SimpleExpression
-
- Referenced by: -
- - -====================================================================================================================== -Having -====================================================================================================================== - - -.. raw:: html - - - - - - HAVING - - Expression - -
- -
Having   ::= 'HAVING' Expression
-
- Referenced by: -
- - -====================================================================================================================== -OrderByElements -====================================================================================================================== - - -.. raw:: html - - - - - - ORDER - - SIBLINGS - - BY - - OrderByElement - , - - -
- - -
         ::= 'ORDER' 'SIBLINGS'? 'BY' OrderByElement ( ',' OrderByElement )*
-
- - -====================================================================================================================== -OrderByElement -====================================================================================================================== - - -.. raw:: html - - - - - - Expression - ASC - - DESC - - NULLS - - FIRST - - LAST - - -
- - -
         ::= Expression ( 'ASC' | 'DESC' )? ( 'NULLS' ( 'FIRST' | 'LAST' )? )?
-
- Referenced by: -
- - -====================================================================================================================== -SimpleJdbcParameter -====================================================================================================================== - - -.. raw:: html - - - - - - ? - - S_LONG - -
- - -
         ::= '?' S_LONG?
-
- - -====================================================================================================================== -SimpleJdbcNamedParameter -====================================================================================================================== - - -.. raw:: html - - - - - - : - - RelObjectNameExt - -
- - -
         ::= ':' RelObjectNameExt
-
- Referenced by: -
- - -====================================================================================================================== -LimitWithOffset -====================================================================================================================== - - -.. raw:: html - - - - - - LIMIT - - Expression - , - - Expression - - PlainLimit - -
- - -
         ::= 'LIMIT' Expression ',' Expression
-
           | PlainLimit
-
- - -====================================================================================================================== -PlainLimit -====================================================================================================================== - - -.. raw:: html - - - - - - LIMIT - - ParenthesedSelect - - Expression - -
- - -
         ::= 'LIMIT' ( ParenthesedSelect | Expression )
-
- Referenced by: -
- - -====================================================================================================================== -LimitBy -====================================================================================================================== - - -.. raw:: html - - - - - - LimitWithOffset - BY - - ExpressionList - -
- - -
- Referenced by: -
- - -====================================================================================================================== -Offset -====================================================================================================================== - - -.. raw:: html - - - - - - OFFSET - - Expression - ROWS - - ROW - - -
- -
Offset   ::= 'OFFSET' Expression ( 'ROWS' | 'ROW' )?
-
- - -====================================================================================================================== -Fetch -====================================================================================================================== - - -.. raw:: html - - - - - - FETCH - - FIRST - - NEXT - - Expression - ROWS - - ROW - - ONLY - - -
- -
Fetch    ::= 'FETCH' ( 'FIRST' | 'NEXT' ) Expression ( 'ROWS' | 'ROW' ) 'ONLY'
-
- - -====================================================================================================================== -WithIsolation -====================================================================================================================== - - -.. raw:: html - - - - - - WITH - - K_ISOLATION - -
- - -
         ::= 'WITH' K_ISOLATION
-
- - -====================================================================================================================== -OptimizeFor -====================================================================================================================== - - -.. raw:: html - - - - - - OPTIMIZE - - FOR - - S_LONG - ROWS - - -
- - -
         ::= 'OPTIMIZE' 'FOR' S_LONG 'ROWS'
-
- Referenced by: -
- - -====================================================================================================================== -Top -====================================================================================================================== - - -.. raw:: html - - - - - - TOP - - S_LONG - - SimpleJdbcParameter - : - - S_IDENTIFIER - ( - - AdditiveExpression - ) - - PERCENT - - WITH TIES - - -
- -
Top      ::= 'TOP' ( S_LONG | SimpleJdbcParameter | ':' S_IDENTIFIER? | '(' AdditiveExpression ')' ) 'PERCENT'? 'WITH TIES'?
-
- Referenced by: -
- - -====================================================================================================================== -Skip -====================================================================================================================== - - -.. raw:: html - - - - - - SKIP - - S_LONG - - S_IDENTIFIER - - SimpleJdbcParameter - -
- -
Skip     ::= 'SKIP' ( S_LONG | S_IDENTIFIER | SimpleJdbcParameter )
-
- Referenced by: -
- - -====================================================================================================================== -First -====================================================================================================================== - - -.. raw:: html - - - - - - FIRST - - LIMIT - - S_LONG - - S_IDENTIFIER - - SimpleJdbcParameter - -
- -
First    ::= ( 'FIRST' | 'LIMIT' ) ( S_LONG | S_IDENTIFIER | SimpleJdbcParameter )
-
- Referenced by: -
- - -====================================================================================================================== -Expression -====================================================================================================================== - - -.. raw:: html - - - - - - XorExpression - -
- - -
         ::= XorExpression
-
- - -====================================================================================================================== -XorExpression -====================================================================================================================== - - -.. raw:: html - - - - - - OrExpression - XOR - - -
- - -
         ::= OrExpression ( 'XOR' OrExpression )*
-
- Referenced by: -
- - -====================================================================================================================== -OrExpression -====================================================================================================================== - - -.. raw:: html - - - - - - AndExpression - OR - - -
- - -
         ::= AndExpression ( 'OR' AndExpression )*
-
- Referenced by: -
- - -====================================================================================================================== -AndExpression -====================================================================================================================== - - -.. raw:: html - - - - - - Condition - NOT - - ! - - ( - - XorExpression - ) - - AND - - && - - -
- - -
         ::= ( Condition | ( 'NOT' | '!' )? '(' XorExpression ')' ) ( ( 'AND' | '&&' ) ( Condition | ( 'NOT' | '!' )? '(' XorExpression ')' ) )*
-
- - -====================================================================================================================== -Condition -====================================================================================================================== - - -.. raw:: html - - - - - - NOT - - ! - - RegularCondition - - SQLCondition - -
- - -
         ::= ( 'NOT' | '!' )? ( RegularCondition | SQLCondition )
-
- - -====================================================================================================================== -OverlapsCondition -====================================================================================================================== - - -.. raw:: html - - - - - - ParenthesedExpressionList - OVERLAPS - - ParenthesedExpressionList - -
- - -
         ::= ParenthesedExpressionList 'OVERLAPS' ParenthesedExpressionList
-
- Referenced by: -
- - -====================================================================================================================== -RegularCondition -====================================================================================================================== - - -.. raw:: html - - - - - - PRIOR - - ComparisonItem - ( - - + - - ) - - > - - < - - = - - OP_GREATERTHANEQUALS - - OP_MINORTHANEQUALS - - OP_NOTEQUALSSTANDARD - - OP_NOTEQUALSBANG - @@ - - ~ - - NOT - - REGEXP - - RLIKE - - BINARY - - ~* - - !~ - - !~* - - @> - - <@ - - ? - - ?| - - ?& - - OP_CONCAT - - - - -# - - <-> - - <#> - - PRIOR - - ComparisonItem - ( - - + - - ) - - -
- - -
         ::= 'PRIOR'? ComparisonItem ( '(' '+' ')' )? ( '>' | '<' | '=' | OP_GREATERTHANEQUALS | OP_MINORTHANEQUALS | OP_NOTEQUALSSTANDARD | OP_NOTEQUALSBANG | '@@' | '~' | ( 'NOT'? 'REGEXP' | 'RLIKE' ) 'BINARY'? | '~*' | '!~' | '!~*' | '@>' - | '<@' | '?' | '?|' | '?&' | OP_CONCAT | '-' | '-#' | '<->' | '<#>' ) 'PRIOR'? ComparisonItem ( '(' '+' ')' )?
-
- Referenced by: -
- - -====================================================================================================================== -SQLCondition -====================================================================================================================== - - -.. raw:: html - - - - - - ExistsExpression - - InExpression - - OverlapsCondition - - SimpleExpression - - Between - - MemberOfExpression - - IsNullExpression - - IsBooleanExpression - - LikeExpression - - IsDistinctExpression - - SimilarToExpression - -
- - -
         ::= ExistsExpression
-
           | InExpression
-
           | OverlapsCondition
-
-
- Referenced by: -
- - -====================================================================================================================== -InExpression -====================================================================================================================== - - -.. raw:: html - - - - - - SimpleExpression - ( - - + - - ) - - NOT - - IN - - S_CHAR_LITERAL - - Function - - ParenthesedSelect - - ParenthesedExpressionList - - SimpleExpression - -
- - -
         ::= SimpleExpression ( '(' '+' ')' )? 'NOT'? 'IN' ( S_CHAR_LITERAL | Function | ParenthesedSelect | ParenthesedExpressionList | SimpleExpression )
-
- Referenced by: -
- - -====================================================================================================================== -Between -====================================================================================================================== - - -.. raw:: html - - - - - - NOT - - BETWEEN - - SimpleExpression - AND - - SimpleExpression - -
- -
Between  ::= 'NOT'? 'BETWEEN' SimpleExpression 'AND' SimpleExpression
-
- Referenced by: -
- - -====================================================================================================================== -LikeExpression -====================================================================================================================== - - -.. raw:: html - - - - - - NOT - - LIKE - - ILIKE - - SimpleExpression - ESCAPE - - S_CHAR_LITERAL - - Expression - -
- - -
         ::= 'NOT'? ( 'LIKE' | 'ILIKE' ) SimpleExpression ( 'ESCAPE' ( S_CHAR_LITERAL | Expression ) )?
-
- Referenced by: -
- - -====================================================================================================================== -SimilarToExpression -====================================================================================================================== - - -.. raw:: html - - - - - - NOT - - SIMILAR - - TO - - SimpleExpression - ESCAPE - - S_CHAR_LITERAL - -
- - -
         ::= 'NOT'? 'SIMILAR' 'TO' SimpleExpression ( 'ESCAPE' S_CHAR_LITERAL )?
-
- Referenced by: -
- - -====================================================================================================================== -IsDistinctExpression -====================================================================================================================== - - -.. raw:: html - - - - - - IS - - NOT - - DISTINCT - - FROM - - SimpleExpression - -
- - -
         ::= 'IS' 'NOT'? 'DISTINCT' 'FROM' SimpleExpression
-
- Referenced by: -
- - -====================================================================================================================== -IsNullExpression -====================================================================================================================== - - -.. raw:: html - - - - - - ISNULL - - IS - - NOT - - NULL - - -
- - -
         ::= 'ISNULL'
-
           | 'IS' 'NOT'? 'NULL'
-
- Referenced by: -
- - -====================================================================================================================== -IsBooleanExpression -====================================================================================================================== - - -.. raw:: html - - - - - - IS - - NOT - - TRUE - - FALSE - - -
- - -
         ::= 'IS' 'NOT'? ( 'TRUE' | 'FALSE' )
-
- Referenced by: -
- - -====================================================================================================================== -ExistsExpression -====================================================================================================================== - - -.. raw:: html - - - - - - EXISTS - - SimpleExpression - -
- - -
         ::= 'EXISTS' SimpleExpression
-
- Referenced by: -
- - -====================================================================================================================== -MemberOfExpression -====================================================================================================================== - - -.. raw:: html - - - - - - MEMBER - - OF - - Expression - -
- - -
         ::= 'MEMBER' 'OF' Expression
-
- Referenced by: -
- - -====================================================================================================================== -ExpressionList -====================================================================================================================== - - -.. raw:: html - - - - - - ComplexExpressionList - - SimpleExpressionList - - ParenthesedExpressionList - -
- - -
         ::= ComplexExpressionList
-
           | SimpleExpressionList
-
           | ParenthesedExpressionList
-
- - -====================================================================================================================== -ParenthesedExpressionList -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - ComplexExpressionList - - SimpleExpressionList - ) - - -
- - -
         ::= '(' ( ComplexExpressionList | SimpleExpressionList )? ')'
-
- - -====================================================================================================================== -SimpleExpressionList -====================================================================================================================== - - -.. raw:: html - - - - - - SimpleExpression - , - - -
- - -
         ::= SimpleExpression ( ',' SimpleExpression )*
-
- - -====================================================================================================================== -ColumnList -====================================================================================================================== - - -.. raw:: html - - - - - - Column - , - - -
- - -
         ::= Column ( ',' Column )*
-
- - -====================================================================================================================== -ParenthesedColumnList -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - ColumnList - ) - - -
- - -
         ::= '(' ColumnList ')'
-
- Referenced by: -
- - -====================================================================================================================== -ComplexExpressionList -====================================================================================================================== - - -.. raw:: html - - - - - - OracleNamedFunctionParameter - - Expression - , - - -
- - - -
- - -====================================================================================================================== -NamedExpressionListExprFirst -====================================================================================================================== - - -.. raw:: html - - - - - - SimpleExpression - FROM - - IN - - PLACING - - SimpleExpression - FOR - - FROM - - SimpleExpression - FOR - - SimpleExpression - -
- - -
         ::= SimpleExpression ( 'FROM' | 'IN' | 'PLACING' ) SimpleExpression ( ( 'FOR' | 'FROM' ) SimpleExpression ( 'FOR' SimpleExpression )? )?
-
- - -====================================================================================================================== -ComparisonItem -====================================================================================================================== - - -.. raw:: html - - - - - - AnyComparisonExpression - - SimpleExpression - - ParenthesedExpressionList - - RowConstructor - - PrimaryExpression - -
- - -
         ::= AnyComparisonExpression
-
           | SimpleExpression
-
           | ParenthesedExpressionList
-
           | RowConstructor
-
           | PrimaryExpression
-
- Referenced by: -
- - -====================================================================================================================== -AnyComparisonExpression -====================================================================================================================== - - -.. raw:: html - - - - - - ANY - - SOME - - ALL - - Select - -
- - -
         ::= ( 'ANY' | 'SOME' | 'ALL' ) Select
-
- Referenced by: -
- - -====================================================================================================================== -SimpleExpression -====================================================================================================================== - - -.. raw:: html - - - - - - UserVariable - = - - := - - ConcatExpression - -
- - -
         ::= ( UserVariable ( '=' | ':=' ) )? ConcatExpression
-
- - -====================================================================================================================== -ConcatExpression -====================================================================================================================== - - -.. raw:: html - - - - - - BitwiseAndOr - - OP_CONCAT - -
- - -
         ::= BitwiseAndOr ( OP_CONCAT BitwiseAndOr )*
-
- Referenced by: -
- - -====================================================================================================================== -BitwiseAndOr -====================================================================================================================== - - -.. raw:: html - - - - - - AdditiveExpression - | - - & - - << - - >> - - -
- - -
         ::= AdditiveExpression ( ( '|' | '&' | '<<' | '>>' ) AdditiveExpression )*
-
- Referenced by: -
- - -====================================================================================================================== -AdditiveExpression -====================================================================================================================== - - -.. raw:: html - - - - - - MultiplicativeExpression - + - - - - - -
- - -
         ::= MultiplicativeExpression ( ( '+' | '-' ) MultiplicativeExpression )*
-
- Referenced by: -
- - -====================================================================================================================== -MultiplicativeExpression -====================================================================================================================== - - -.. raw:: html - - - - - - BitwiseXor - * - - / - - DIV - - % - - -
- - -
         ::= BitwiseXor ( ( '*' | '/' | 'DIV' | '%' ) BitwiseXor )*
-
- Referenced by: -
- - -====================================================================================================================== -BitwiseXor -====================================================================================================================== - - -.. raw:: html - - - - - - PrimaryExpression - ^ - - -
- - -
         ::= PrimaryExpression ( '^' PrimaryExpression )*
-
- Referenced by: -
- - -====================================================================================================================== -ArrayExpression -====================================================================================================================== - - -.. raw:: html - - - - - - [ - - SimpleExpression - : - - SimpleExpression - ] - - -
- - -
         ::= ( '[' SimpleExpression? ( ':' SimpleExpression? )? ']' )+
-
- Referenced by: -
- - -====================================================================================================================== -PrimaryExpression -====================================================================================================================== - - -.. raw:: html - - - - - - NOT - - ! - - + - - - - - ~ - - NULL - - CaseWhenExpression - - SimpleJdbcParameter - - JdbcNamedParameter - - UserVariable - - NumericBind - - ExtractExpression - - MySQLGroupConcat - - XMLSerializeExpr - - JsonExpression - - JsonFunction - - JsonAggregateFunction - - FullTextSearch - - Function - - AnalyticExpression - - IntervalExpression - - S_DOUBLE - - S_LONG - - S_HEX - - CastExpression - - CharacterPrimary - - K_TIME_KEY_EXPR - CURRENT - - DateTimeLiteralExpression - ARRAY - - ArrayConstructor - - NextValExpression - - ConnectByRootOperator - ALL - - Column - - S_CHAR_LITERAL - {d - - {t - - {ts - - S_CHAR_LITERAL - } - - ParenthesedSelect - - ParenthesedExpressionList - . - - RelObjectNameExt - COLLATE - - S_IDENTIFIER - - IntervalExpressionWithoutInterval - - ArrayExpression - :: - - ColDataType - AT - - K_DATETIMELITERAL - ZONE - - PrimaryExpression - -
- - -
         ::= ( 'NOT' | '!' )? ( '+' | '-' | '~' )? ( 'NULL' | CaseWhenExpression | SimpleJdbcParameter | JdbcNamedParameter | UserVariable | NumericBind | ExtractExpression | MySQLGroupConcat | XMLSerializeExpr | JsonExpression | JsonFunction | JsonAggregateFunction | FullTextSearch | Function AnalyticExpression? | IntervalExpression | S_DOUBLE | S_LONG | S_HEX | CastExpression | CharacterPrimary | K_TIME_KEY_EXPR | 'CURRENT' | DateTimeLiteralExpression | 'ARRAY' ArrayConstructor | NextValExpression | ConnectByRootOperator | 'ALL' | Column | S_CHAR_LITERAL | ( '{d' | '{t' | '{ts' ) S_CHAR_LITERAL '}' | ParenthesedSelect | ParenthesedExpressionList ( '.' RelObjectNameExt )? ) ( 'COLLATE' S_IDENTIFIER )? IntervalExpressionWithoutInterval? ArrayExpression? ( '::' ColDataType )* ( 'AT' K_DATETIMELITERAL 'ZONE' PrimaryExpression )*
-
- - -====================================================================================================================== -ConnectByRootOperator -====================================================================================================================== - - -.. raw:: html - - - - - - CONNECT_BY_ROOT - - Column - -
- - -
         ::= 'CONNECT_BY_ROOT' Column
-
- Referenced by: -
- - -====================================================================================================================== -NextValExpression -====================================================================================================================== - - -.. raw:: html - - - - - - K_NEXTVAL - - RelObjectNameList - -
- - -
         ::= K_NEXTVAL RelObjectNameList
-
- Referenced by: -
- - -====================================================================================================================== -JdbcNamedParameter -====================================================================================================================== - - -.. raw:: html - - - - - - : - - & - - IdentifierChain - -
- - -
         ::= ( ':' | '&' ) IdentifierChain
-
- - -====================================================================================================================== -OracleNamedFunctionParameter -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameExt2 - => - - Expression - -
- - -
         ::= RelObjectNameExt2 '=>' Expression
-
- Referenced by: -
- - -====================================================================================================================== -UserVariable -====================================================================================================================== - - -.. raw:: html - - - - - - @ - - @@ - - IdentifierChain - -
- - -
         ::= ( '@' | '@@' ) IdentifierChain
-
- - -====================================================================================================================== -NumericBind -====================================================================================================================== - - -.. raw:: html - - - - - - : - - S_LONG - -
- - -
         ::= ':' S_LONG
-
- Referenced by: -
- - -====================================================================================================================== -DateTimeLiteralExpression -====================================================================================================================== - - -.. raw:: html - - - - - - K_DATETIMELITERAL - - S_CHAR_LITERAL - -
- - -
         ::= K_DATETIMELITERAL S_CHAR_LITERAL
-
- Referenced by: -
- - -====================================================================================================================== -RangeExpression -====================================================================================================================== - - -.. raw:: html - - - - - - : - - Expression - -
- - -
         ::= ':' Expression
-
- Referenced by: -
- - -====================================================================================================================== -ArrayConstructor -====================================================================================================================== - - -.. raw:: html - - - - - - [ - - Expression - - RangeExpression - - ArrayConstructor - , - - ] - - -
- - -
         ::= '[' ( ( Expression RangeExpression? | ArrayConstructor ) ( ',' ( Expression RangeExpression? | ArrayConstructor ) )* )? ']'
-
- - -====================================================================================================================== -ParenthesedExpression -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - PrimaryExpression - ) - - -
- - -
         ::= '(' PrimaryExpression ')'
-
- Referenced by: -
- - -====================================================================================================================== -JsonExpression -====================================================================================================================== - - -.. raw:: html - - - - - - CaseWhenExpression - - SimpleJdbcParameter - - JdbcNamedParameter - - UserVariable - - JsonFunction - - JsonAggregateFunction - - FullTextSearch - - Function - - Column - - S_CHAR_LITERAL - - ParenthesedExpression - - ParenthesedSelect - :: - - ColDataType - -> - - ->> - - S_CHAR_LITERAL - - S_LONG - #> - - #>> - - S_CHAR_LITERAL - :: - - ColDataType - -> - - ->> - - S_CHAR_LITERAL - - S_LONG - #> - - #>> - - S_CHAR_LITERAL - -
- - -
         ::= ( CaseWhenExpression | SimpleJdbcParameter | JdbcNamedParameter | UserVariable | JsonFunction | JsonAggregateFunction | FullTextSearch | Function | Column | S_CHAR_LITERAL | ParenthesedExpression | ParenthesedSelect ) ( '::' ColDataType )* ( ( '->' | '->>' ) ( S_CHAR_LITERAL | S_LONG ) | ( '#>' | '#>>' ) S_CHAR_LITERAL )+ ( ( '::' ColDataType )+ ( ( '->' | '->>' ) ( S_CHAR_LITERAL | S_LONG ) | ( '#>' | '#>>' ) S_CHAR_LITERAL )* )*
-
- Referenced by: -
- - -====================================================================================================================== -JsonFunction -====================================================================================================================== - - -.. raw:: html - - - - - - JSON_OBJECT - - ( - - KEY - - S_CHAR_LITERAL - : - - , - - VALUE - - Expression - FORMAT - - JSON - - , - - KEY - - S_CHAR_LITERAL - : - - , - - VALUE - - Expression - FORMAT - - JSON - - NULL - - ABSENT - - ON - - NULL - - WITH - - WITHOUT - - UNIQUE - - KEYS - - JSON_ARRAY - - ( - - NULL - - ON - - NULL - - Expression - FORMAT - - JSON - - , - - ABSENT - - ON - - NULL - - ) - - -
- - -
         ::= ( 'JSON_OBJECT' '(' ( 'KEY'? S_CHAR_LITERAL ( ( ':' | ',' | 'VALUE' ) Expression ( 'FORMAT' 'JSON' )? )? ( ',' 'KEY'? S_CHAR_LITERAL ( ':' | ',' | 'VALUE' ) Expression ( 'FORMAT' 'JSON' )? )* )? ( ( 'NULL' | 'ABSENT' ) 'ON' 'NULL' )? ( ( 'WITH' | 'WITHOUT' - ) 'UNIQUE' 'KEYS' )? | 'JSON_ARRAY' '(' ( 'NULL' 'ON' 'NULL' | Expression ( 'FORMAT' 'JSON' )? ( ',' Expression ( 'FORMAT' 'JSON' )? )* )* ( 'ABSENT' 'ON' 'NULL' )? ) ')'
-
- - -====================================================================================================================== -JsonAggregateFunction -====================================================================================================================== - - -.. raw:: html - - - - - - JSON_OBJECTAGG - - ( - - KEY - - DT_ZONE - - S_DOUBLE - - S_LONG - - S_HEX - - S_CHAR_LITERAL - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - : - - VALUE - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - FORMAT - - JSON - - NULL - - ABSENT - - ON - - NULL - - WITH - - WITHOUT - - UNIQUE - - KEYS - - JSON_ARRAYAGG - - ( - - Expression - FORMAT - - JSON - - OrderByElements - NULL - - ABSENT - - ON - - NULL - - ) - - FILTER - - ( - - WHERE - - Expression - ) - - OVER - - ( - - PARTITION - - BY - - ComplexExpressionList - ( - - ComplexExpressionList - ) - - OrderByElements - - WindowElement - ) - - -
- - -
         ::= ( 'JSON_OBJECTAGG' '(' 'KEY'? ( DT_ZONE | S_DOUBLE | S_LONG | S_HEX | S_CHAR_LITERAL | S_IDENTIFIER | S_QUOTED_IDENTIFIER ) ( ':' | 'VALUE' ) ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) ( 'FORMAT' 'JSON' )? ( ( 'NULL' | 'ABSENT' ) 'ON' 'NULL' )? ( ( 'WITH' | 'WITHOUT' - ) 'UNIQUE' 'KEYS' )? | 'JSON_ARRAYAGG' '(' Expression ( 'FORMAT' 'JSON' )? OrderByElements? ( ( 'NULL' | 'ABSENT' ) 'ON' 'NULL' )? ) ')' ( 'FILTER' '(' 'WHERE' Expression ')' )? ( 'OVER' '(' ( 'PARTITION' 'BY' ( ComplexExpressionList | '(' ComplexExpressionList ')' ) )? OrderByElements? WindowElement? ')' )?
-
- - -====================================================================================================================== -IntervalExpression -====================================================================================================================== - - -.. raw:: html - - - - - - INTERVAL - - - - - S_LONG - - S_DOUBLE - - S_CHAR_LITERAL - - SimpleJdbcParameter - - JdbcNamedParameter - - Function - - Column - - S_IDENTIFIER - - K_DATE_LITERAL - -
- - - -
- Referenced by: -
- - -====================================================================================================================== -IntervalExpressionWithoutInterval -====================================================================================================================== - - -.. raw:: html - - - - - - K_DATE_LITERAL - -
- - -
         ::= K_DATE_LITERAL
-
- Referenced by: -
- - -====================================================================================================================== -KeepExpression -====================================================================================================================== - - -.. raw:: html - - - - - - KEEP - - ( - - S_IDENTIFIER - FIRST - - LAST - - OrderByElements - ) - - -
- - -
         ::= 'KEEP' '(' S_IDENTIFIER ( 'FIRST' | 'LAST' ) OrderByElements ')'
-
- Referenced by: -
- - -====================================================================================================================== -windowFun -====================================================================================================================== - - -.. raw:: html - - - - - - IGNORE - - NULLS - - OVER - - WITHIN - - GROUP - - RelObjectName - - windowDefinition - OVER - - ( - - PARTITION - - BY - - ComplexExpressionList - ( - - ComplexExpressionList - ) - - ) - - -
- - -
         ::= ( ( 'IGNORE' 'NULLS' )? 'OVER' | 'WITHIN' 'GROUP' ) ( RelObjectName | windowDefinition ( 'OVER' '(' ( 'PARTITION' 'BY' ( ComplexExpressionList | '(' ComplexExpressionList ')' ) )? ')' )? )
-
- Referenced by: -
- - -====================================================================================================================== -windowDefinition -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - PARTITION - - BY - - ComplexExpressionList - ( - - ComplexExpressionList - ) - - OrderByElements - - WindowElement - ) - - -
- - -
         ::= '(' ( 'PARTITION' 'BY' ( ComplexExpressionList | '(' ComplexExpressionList ')' ) )? OrderByElements? WindowElement? ')'
-
- Referenced by: -
- - -====================================================================================================================== -AnalyticExpression -====================================================================================================================== - - -.. raw:: html - - - - - - FILTER - - ( - - WHERE - - Expression - ) - - windowFun - - windowFun - -
- - -
         ::= 'FILTER' '(' 'WHERE' Expression ')' windowFun?
-
           | windowFun
-
- Referenced by: -
- - -====================================================================================================================== -WindowElement -====================================================================================================================== - - -.. raw:: html - - - - - - ROWS - - RANGE - - BETWEEN - - WindowOffset - AND - - WindowOffset - -
- - -
         ::= ( 'ROWS' | 'RANGE' ) ( 'BETWEEN' WindowOffset 'AND' )? WindowOffset
-
- - -====================================================================================================================== -WindowOffset -====================================================================================================================== - - -.. raw:: html - - - - - - UNBOUNDED - - SimpleExpression - PRECEDING - - FOLLOWING - - CURRENT - - ROW - - -
- - -
         ::= ( 'UNBOUNDED' | SimpleExpression ) ( 'PRECEDING' | 'FOLLOWING' )
-
           | 'CURRENT' 'ROW'
-
- Referenced by: -
- - -====================================================================================================================== -ExtractExpression -====================================================================================================================== - - -.. raw:: html - - - - - - EXTRACT - - ( - - RelObjectName - - S_CHAR_LITERAL - FROM - - SimpleExpression - ) - - -
- - -
         ::= 'EXTRACT' '(' ( RelObjectName | S_CHAR_LITERAL ) 'FROM' SimpleExpression ')'
-
- Referenced by: -
- - -====================================================================================================================== -CastExpression -====================================================================================================================== - - -.. raw:: html - - - - - - CAST - - SAFE_CAST - - TRY_CAST - - ( - - SimpleExpression - AS - - ROW - - ( - - ColumnDefinition - , - - ) - - ColDataType - ) - - -
- - -
         ::= ( 'CAST' | 'SAFE_CAST' | 'TRY_CAST' ) '(' SimpleExpression 'AS' ( 'ROW' '(' ColumnDefinition ( ',' ColumnDefinition )* ')' | ColDataType ) ')'
-
- Referenced by: -
- - -====================================================================================================================== -CaseWhenExpression -====================================================================================================================== - - -.. raw:: html - - - - - - CASE - - Expression - - WhenThenSearchCondition - ELSE - - ( - - CaseWhenExpression - ) - - CaseWhenExpression - - Expression - - SimpleExpression - END - - -
- - -
         ::= 'CASE' Expression? WhenThenSearchCondition+ ( 'ELSE' ( '(' CaseWhenExpression ')' | CaseWhenExpression | Expression | SimpleExpression ) )? 'END'
-
- - -====================================================================================================================== -WhenThenSearchCondition -====================================================================================================================== - - -.. raw:: html - - - - - - WHEN - - Expression - THEN - - Expression - - SimpleExpression - -
- - -
         ::= 'WHEN' Expression 'THEN' ( Expression | SimpleExpression )
-
- Referenced by: -
- - -====================================================================================================================== -RowConstructor -====================================================================================================================== - - -.. raw:: html - - - - - - ROW - - ParenthesedExpressionList - -
- - -
         ::= 'ROW' ParenthesedExpressionList
-
- Referenced by: -
- - -====================================================================================================================== -VariableExpression -====================================================================================================================== - - -.. raw:: html - - - - - - UserVariable - = - - SimpleExpression - -
- - -
         ::= UserVariable '=' SimpleExpression
-
- Not referenced by any. -
- - -====================================================================================================================== -Execute -====================================================================================================================== - - -.. raw:: html - - - - - - EXEC - - EXECUTE - - CALL - - RelObjectNameList - - ExpressionList - -
- -
Execute  ::= ( 'EXEC' | 'EXECUTE' | 'CALL' ) RelObjectNameList ExpressionList?
-
- Referenced by: -
- - -====================================================================================================================== -FullTextSearch -====================================================================================================================== - - -.. raw:: html - - - - - - MATCH - - ( - - ColumnList - ) - - AGAINST - - ( - - S_CHAR_LITERAL - - SimpleJdbcParameter - - SimpleJdbcNamedParameter - IN NATURAL LANGUAGE MODE - - IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION - - IN BOOLEAN MODE - - WITH QUERY EXPANSION - - ) - - -
- - -
         ::= 'MATCH' '(' ColumnList ')' 'AGAINST' '(' ( S_CHAR_LITERAL | SimpleJdbcParameter | SimpleJdbcNamedParameter ) ( 'IN NATURAL LANGUAGE MODE' | 'IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION' - | 'IN BOOLEAN MODE' | 'WITH QUERY EXPANSION' )? ')'
-
- - -====================================================================================================================== -Function -====================================================================================================================== - - -.. raw:: html - - - - - - { - - FN - - InternalFunction - } - - SpecialStringFunctionWithNamedParameters - - InternalFunction - -
- -
Function ::= '{' 'FN' InternalFunction '}'
- -
           | InternalFunction
-
- - -====================================================================================================================== -SpecialStringFunctionWithNamedParameters -====================================================================================================================== - - -.. raw:: html - - - - - - K_STRING_FUNCTION_NAME - ( - - NamedExpressionListExprFirst - - ExpressionList - ) - - -
- - - -
- Referenced by: -
- - -====================================================================================================================== -InternalFunction -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameList - ( - - DISTINCT - - ALL - - UNIQUE - - * - - AllTableColumns - - ExpressionList - - OrderByElements - - Select - IGNORE - - NULLS - - ) - - . - - Function - - Column - - KeepExpression - -
- - -
         ::= RelObjectNameList '(' ( ( 'DISTINCT' | 'ALL' | 'UNIQUE' )? ( '*' | AllTableColumns | ExpressionList OrderByElements? | Select ) )? ( 'IGNORE' 'NULLS' )? ')' ( '.' ( Function | Column ) )? KeepExpression?
-
- Referenced by: -
- - -====================================================================================================================== -XMLSerializeExpr -====================================================================================================================== - - -.. raw:: html - - - - - - XMLSERIALIZE - - ( - - XMLAGG - - ( - - XMLTEXT - - ( - - SimpleExpression - ) - - OrderByElements - ) - - AS - - ColDataType - ) - - -
- - -
         ::= 'XMLSERIALIZE' '(' 'XMLAGG' '(' 'XMLTEXT' '(' SimpleExpression ')' OrderByElements? ')' 'AS' ColDataType ')'
-
- Referenced by: -
- - -====================================================================================================================== -MySQLGroupConcat -====================================================================================================================== - - -.. raw:: html - - - - - - GROUP_CONCAT - - ( - - DISTINCT - - ExpressionList - - OrderByElements - SEPARATOR - - S_CHAR_LITERAL - ) - - -
- - -
         ::= 'GROUP_CONCAT' '(' 'DISTINCT'? ExpressionList OrderByElements? ( 'SEPARATOR' S_CHAR_LITERAL )? ')'
-
- Referenced by: -
- - -====================================================================================================================== -TableFunction -====================================================================================================================== - - -.. raw:: html - - - - - - Function - - Alias - -
- - -
         ::= Function Alias?
-
- Referenced by: -
- - -====================================================================================================================== -ColumnNamesWithParamsList -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - RelObjectName - - CreateParameter - , - - ) - - -
- - -
         ::= '(' RelObjectName CreateParameter? ( ',' RelObjectName CreateParameter? )* ')'
-
- Referenced by: -
- - -====================================================================================================================== -Index -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameList - -
- - -
- Referenced by: -
- - -====================================================================================================================== -CreateIndex -====================================================================================================================== - - -.. raw:: html - - - - - - CreateParameter - INDEX - - Index - ON - - Table - USING - - S_IDENTIFIER - - ColumnNamesWithParamsList - - CreateParameter - -
- - -
         ::= CreateParameter? 'INDEX' Index 'ON' Table ( 'USING' S_IDENTIFIER )? ColumnNamesWithParamsList CreateParameter*
-
- Referenced by: -
- - -====================================================================================================================== -ColumnDefinition -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectName - - ColDataType - - CreateParameter - -
- - - -
- - -====================================================================================================================== -CreateSchema -====================================================================================================================== - - -.. raw:: html - - - - - - SCHEMA - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - AUTHORIZATION - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - - PathSpecification - CREATE - - CreateTable - - CreateView - -
- - -
         ::= 'SCHEMA' ( S_IDENTIFIER | S_QUOTED_IDENTIFIER )? ( 'AUTHORIZATION' ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) )? PathSpecification? ( 'CREATE' CreateTable | CreateView )*
-
- Referenced by: -
- - -====================================================================================================================== -PathSpecification -====================================================================================================================== - - -.. raw:: html - - - - - - PATH - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - , - - -
- - -
         ::= 'PATH' ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) ( ',' ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) )*
-
- Referenced by: -
- - -====================================================================================================================== -CreateTable -====================================================================================================================== - - -.. raw:: html - - - - - - UNLOGGED - - GLOBAL - - CreateParameter - TABLE - - IF - - NOT - - EXISTS - - Table - ( - - ColumnDefinition - , - - INDEX - - UNIQUE - - FULLTEXT - - KEY - - RelObjectName - - ColumnNamesWithParamsList - - CreateParameter - CONSTRAINT - - RelObjectName - PRIMARY - - KEY - - UNIQUE - - KEY - - ColumnNamesWithParamsList - - CreateParameter - FOREIGN - - KEY - - ColumnNamesWithParamsList - REFERENCES - - Table - - ColumnsNamesList - ON - - DELETE - - UPDATE - - Action - ON - - DELETE - - UPDATE - - Action - CHECK - - ( - - Expression - ) - - EXCLUDE - - WHERE - - ( - - Expression - ) - - ColumnDefinition - - RelObjectName - , - - ) - - CreateParameter - - RowMovement - AS - - Select - LIKE - - ( - - Table - ) - - Table - , - - SpannerInterleaveIn - -
- - -
         ::= 'UNLOGGED'? 'GLOBAL'? CreateParameter* 'TABLE' ( 'IF' 'NOT' 'EXISTS' )? Table ( '(' ( RelObjectName ( ',' RelObjectName )* | ColumnDefinition ( ',' ( ( 'INDEX' | 'UNIQUE'? 'FULLTEXT'? 'KEY' ) RelObjectName ColumnNamesWithParamsList CreateParameter* | ( 'CONSTRAINT' RelObjectName )? ( ( 'PRIMARY' 'KEY' | 'UNIQUE' 'KEY'? ) ColumnNamesWithParamsList CreateParameter* | 'FOREIGN' 'KEY' ColumnNamesWithParamsList 'REFERENCES' Table ColumnsNamesList ( 'ON' ( 'DELETE' | 'UPDATE' ) Action )? ( 'ON' ( 'DELETE' | 'UPDATE' ) Action )? | 'CHECK' ( '(' Expression ')' )* ) | 'EXCLUDE' 'WHERE' ( '(' Expression ')' )* | ColumnDefinition ) )* ) ')' )? CreateParameter* RowMovement? ( 'AS' Select )? ( 'LIKE' ( '(' Table ')' | Table ) )? ( ',' SpannerInterleaveIn )?
-
- Referenced by: -
- - -====================================================================================================================== -SpannerInterleaveIn -====================================================================================================================== - - -.. raw:: html - - - - - - INTERLEAVE - - IN - - PARENT - - Table - ON - - DELETE - - NO - - ACTION - - CASCADE - - -
- - -
         ::= 'INTERLEAVE' 'IN' 'PARENT' Table ( 'ON' 'DELETE' ( 'NO' 'ACTION' | 'CASCADE' ) )?
-
- Referenced by: -
- - -====================================================================================================================== -ColDataType -====================================================================================================================== - - -.. raw:: html - - - - - - ARRAY - - < - - ColDataType - > - - BYTES - - STRING - - JSON - - ( - - S_LONG - - S_IDENTIFIER - ) - - CHARACTER - - BIT - - VARYING - - DOUBLE - - PRECISION - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - - K_DATETIMELITERAL - - K_DATE_LITERAL - XML - - INTERVAL - - DT_ZONE - CHAR - - SET - - BINARY - - JSON - - STRING - - . - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - UNSIGNED - - SIGNED - - S_IDENTIFIER - ( - - S_LONG - BYTE - - CHAR - - S_CHAR_LITERAL - - S_IDENTIFIER - CHAR - - , - - ) - - [ - - S_LONG - ] - - CHARACTER - - SET - - S_IDENTIFIER - BINARY - - -
- - -
         ::= ( 'ARRAY' '<' ColDataType '>' | ( 'BYTES' | 'STRING' | 'JSON' ) '(' ( S_LONG | S_IDENTIFIER ) ')' | ( 'CHARACTER' | 'BIT' ) 'VARYING'? | 'DOUBLE' 'PRECISION'? | ( S_IDENTIFIER | S_QUOTED_IDENTIFIER | K_DATETIMELITERAL | K_DATE_LITERAL | 'XML' | 'INTERVAL' | DT_ZONE | 'CHAR' | 'SET' | 'BINARY' | 'JSON' | 'STRING' ) ( '.' ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) )? | ( 'UNSIGNED' | 'SIGNED' ) S_IDENTIFIER? ) ( '(' ( ( S_LONG ( 'BYTE' | 'CHAR' )? | S_CHAR_LITERAL | S_IDENTIFIER | 'CHAR' ) ','? )* ')' )? ( '[' S_LONG? ']' )* ( 'CHARACTER' 'SET' ( S_IDENTIFIER | 'BINARY' ) )?
-
- - -====================================================================================================================== -Analyze -====================================================================================================================== - - -.. raw:: html - - - - - - ANALYZE - - Table - -
- -
Analyze  ::= 'ANALYZE' Table
-
- Referenced by: -
- - -====================================================================================================================== -CreateView -====================================================================================================================== - - -.. raw:: html - - - - - - NO - - FORCE - - TEMP - - TEMPORARY - - MATERIALIZED - - VIEW - - Table - AUTO - - REFRESH - - YES - - NO - - IF - - NOT - - EXISTS - - ColumnsNamesList - AS - - Select - WITH - - READ - - ONLY - - -
- - -
         ::= ( 'NO'? 'FORCE' )? ( 'TEMP' | 'TEMPORARY' )? 'MATERIALIZED'? 'VIEW' Table ( 'AUTO' 'REFRESH' ( 'YES' | 'NO' ) )? ( 'IF' 'NOT' 'EXISTS' )? ColumnsNamesList? 'AS' Select ( 'WITH' 'READ' 'ONLY' )?
-
- Referenced by: -
- - -====================================================================================================================== -Action -====================================================================================================================== - - -.. raw:: html - - - - - - CASCADE - - RESTRICT - - NO - - ACTION - - SET - - NULL - - DEFAULT - - -
- -
Action   ::= 'CASCADE'
-
           | 'RESTRICT'
-
           | 'NO' 'ACTION'
-
           | 'SET' ( 'NULL' | 'DEFAULT' )
-
- Referenced by: -
- - -====================================================================================================================== -AlterView -====================================================================================================================== - - -.. raw:: html - - - - - - VIEW - - Table - - ColumnsNamesList - AS - - Select - -
- - -
         ::= 'VIEW' Table ColumnsNamesList? 'AS' Select
-
- Referenced by: -
- - -====================================================================================================================== -CreateParameter -====================================================================================================================== - - -.. raw:: html - - - - - - K_NEXTVAL - ( - - S_CHAR_LITERAL - :: - - ColDataType - ) - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - . - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - USING - - INDEX - - TABLESPACE - - RelObjectName - - S_CHAR_LITERAL - NULL - - NOT - - PRIMARY - - FOREIGN - - REFERENCES - - KEY - - STORED - - ON - - COMMIT - - DROP - - ROWS - - UNIQUE - - CASCADE - - DELETE - - UPDATE - - CONSTRAINT - - WITH - - EXCLUDE - - WHERE - - UNSIGNED - - TEMP - - TEMPORARY - - PARTITION - - BY - - IN - - TYPE - - COMMENT - - USING - - COLLATE - - ASC - - DESC - - TRUE - - FALSE - - PARALLEL - - BINARY - - START - - K_TIME_KEY_EXPR - = - - DEFAULT - - AS - - CHECK - - ( - - Expression - ) - - + - - - - - S_LONG - - S_DOUBLE - - AList - CHARACTER - - SET - - ARRAY - - ArrayConstructor - :: - - ColDataType - -
- - -
         ::= K_NEXTVAL '(' S_CHAR_LITERAL '::' ColDataType ')'
-
           | ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) ( '.' ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) )?
-
           | ( 'USING' 'INDEX' )? 'TABLESPACE' RelObjectName
-
           | S_CHAR_LITERAL
-
           | 'NULL'
-
           | 'NOT'
-
           | 'PRIMARY'
-
           | 'FOREIGN'
-
           | 'REFERENCES'
-
           | 'KEY'
-
           | 'STORED'
-
           | 'ON'
-
           | 'COMMIT'
-
           | 'DROP'
-
           | 'ROWS'
-
           | 'UNIQUE'
-
           | 'CASCADE'
-
           | 'DELETE'
-
           | 'UPDATE'
-
           | 'CONSTRAINT'
-
           | 'WITH'
-
           | 'EXCLUDE'
-
           | 'WHERE'
-
           | 'UNSIGNED'
-
           | 'TEMP'
-
           | 'TEMPORARY'
-
           | 'PARTITION'
-
           | 'BY'
-
           | 'IN'
-
           | 'TYPE'
-
           | 'COMMENT'
-
           | 'USING'
-
           | 'COLLATE'
-
           | 'ASC'
-
           | 'DESC'
-
           | 'TRUE'
-
           | 'FALSE'
-
           | 'PARALLEL'
-
           | 'BINARY'
-
           | 'START'
-
           | K_TIME_KEY_EXPR
-
           | '='
-
           | ( 'DEFAULT' | 'AS' | 'CHECK' ) ( '(' Expression ')' )?
-
           | ( '+' | '-' )? S_LONG
-
           | S_DOUBLE
-
           | AList
-
           | 'CHARACTER' 'SET'
-
           | 'ARRAY' ArrayConstructor
-
           | '::' ColDataType
-
- - -====================================================================================================================== -RowMovement -====================================================================================================================== - - -.. raw:: html - - - - - - ENABLE - - DISABLE - - ROW - - MOVEMENT - - -
- - -
         ::= ( 'ENABLE' | 'DISABLE' ) 'ROW' 'MOVEMENT'
-
- Referenced by: -
- - -====================================================================================================================== -AList -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - S_LONG - - S_DOUBLE - - S_CHAR_LITERAL - - RelObjectNameWithoutValue - , - - = - - ) - - -
- -
AList    ::= '(' ( ( S_LONG | S_DOUBLE | S_CHAR_LITERAL | RelObjectNameWithoutValue ) ( ',' | '=' )? )* ')'
-
- Referenced by: -
- - -====================================================================================================================== -ColumnsNamesListItem -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectName - ( - - S_LONG - ) - - -
- - -
         ::= RelObjectName ( '(' S_LONG ')' )?
-
- Referenced by: -
- - -====================================================================================================================== -ColumnsNamesList -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - ColumnsNamesListItem - , - - ) - - -
- - -
         ::= '(' ColumnsNamesListItem ( ',' ColumnsNamesListItem )* ')'
-
- - -====================================================================================================================== -FuncArgsListItem -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectName - - RelObjectName - ( - - S_LONG - ) - - -
- - -
         ::= RelObjectName RelObjectName? ( '(' S_LONG ')' )?
-
- Referenced by: -
- - -====================================================================================================================== -FuncArgsList -====================================================================================================================== - - -.. raw:: html - - - - - - ( - - FuncArgsListItem - , - - ) - - -
- - -
         ::= '(' ( FuncArgsListItem ( ',' FuncArgsListItem )* )? ')'
-
- Referenced by: -
- - -====================================================================================================================== -Drop -====================================================================================================================== - - -.. raw:: html - - - - - - DROP - - MATERIALIZED - - S_IDENTIFIER - TEMPORARY - - TABLE - - INDEX - - VIEW - - SCHEMA - - SEQUENCE - - FUNCTION - - IF - - EXISTS - - Table - - FuncArgsList - - S_IDENTIFIER - CASCADE - - RESTRICT - - ON - - -
- -
Drop     ::= 'DROP' 'MATERIALIZED'? ( S_IDENTIFIER | 'TEMPORARY'? 'TABLE' | 'INDEX' | 'VIEW' | 'SCHEMA' | 'SEQUENCE' | 'FUNCTION' ) - ( 'IF' 'EXISTS' )? Table FuncArgsList? ( S_IDENTIFIER | 'CASCADE' | 'RESTRICT' | 'ON' )*
-
- Referenced by: -
- - -====================================================================================================================== -Truncate -====================================================================================================================== - - -.. raw:: html - - - - - - TRUNCATE - - TABLE - - ONLY - - Table - CASCADE - - -
- -
Truncate ::= 'TRUNCATE' 'TABLE'? 'ONLY'? Table 'CASCADE'?
-
- Referenced by: -
- - -====================================================================================================================== -AlterExpressionColumnDataType -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectName - TYPE - - ColDataType - - CreateParameter - -
- - -
         ::= RelObjectName 'TYPE'? ColDataType CreateParameter*
-
- Referenced by: -
- - -====================================================================================================================== -AlterExpressionColumnDropNotNull -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectName - DROP - - NOT - - NULL - - -
- - -
         ::= RelObjectName 'DROP' 'NOT'? 'NULL'
-
- Referenced by: -
- - -====================================================================================================================== -AlterExpressionColumnDropDefault -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectName - DROP - - DEFAULT - - -
- - -
         ::= RelObjectName 'DROP' 'DEFAULT'
-
- Referenced by: -
- - -====================================================================================================================== -AlterExpressionConstraintState -====================================================================================================================== - - -.. raw:: html - - - - - - NOT - - DEFERRABLE - - VALIDATE - - NOVALIDATE - - ENABLE - - DISABLE - - -
- - -
         ::= ( 'NOT'? 'DEFERRABLE' | 'VALIDATE' | 'NOVALIDATE' | 'ENABLE' | 'DISABLE' - )*
-
- Referenced by: -
- - -====================================================================================================================== -AlterExpression -====================================================================================================================== - - -.. raw:: html - - - - - - ADD - - ALTER - - MODIFY - - PRIMARY - - KEY - - KEY - - INDEX - - RelObjectName - - ColumnsNamesList - - AlterExpressionConstraintState - UNIQUE - - KEY - - INDEX - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - - ColumnsNamesList - USING - - RelObjectName - COLUMN - - ( - - AlterExpressionColumnDataType - , - - ) - - AlterExpressionColumnDataType - - AlterExpressionColumnDropNotNull - - AlterExpressionColumnDropDefault - ( - - AlterExpressionColumnDataType - , - - ) - - FOREIGN - - KEY - - ColumnsNamesList - REFERENCES - - Table - - ColumnsNamesList - ON - - DELETE - - UPDATE - - Action - ON - - DELETE - - UPDATE - - Action - CONSTRAINT - - RelObjectName - FOREIGN - - KEY - - ColumnsNamesList - REFERENCES - - Table - - ColumnsNamesList - ON - - DELETE - - UPDATE - - Action - ON - - DELETE - - UPDATE - - Action - KEY - - ColumnsNamesList - - AlterExpressionConstraintState - PRIMARY - - KEY - - UNIQUE - - KEY - - INDEX - - ColumnsNamesList - - AlterExpressionConstraintState - USING - - RelObjectName - CHECK - - ( - - Expression - ) - - RelObjectName - COMMENT - - S_CHAR_LITERAL - CHANGE - - COLUMN - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - - AlterExpressionColumnDataType - DROP - - ColumnsNamesList - COLUMN - - IF - - EXISTS - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - INVALIDATE - - CASCADE - - CONSTRAINTS - - INDEX - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - UNIQUE - - FOREIGN - - KEY - - ColumnsNamesList - PRIMARY - - KEY - - CONSTRAINT - - IF - - EXISTS - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - CASCADE - - RESTRICT - - ALGORITHM - - = - - RelObjectName - RENAME - - COLUMN - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - TO - - S_IDENTIFIER - - S_QUOTED_IDENTIFIER - COMMENT - - S_CHAR_LITERAL - - captureRest - -
- - -
         ::= ( 'ADD' | 'ALTER' | 'MODIFY' ) ( ( ( 'PRIMARY' 'KEY' | ( 'KEY' | 'INDEX' - ) RelObjectName ) ColumnsNamesList AlterExpressionConstraintState | 'UNIQUE' ( ( 'KEY' | 'INDEX' ) ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) )? ColumnsNamesList ) ( 'USING' RelObjectName )? | 'COLUMN'? ( '(' AlterExpressionColumnDataType ( ',' AlterExpressionColumnDataType )* ')' | AlterExpressionColumnDataType | AlterExpressionColumnDropNotNull | AlterExpressionColumnDropDefault ) | '(' AlterExpressionColumnDataType ( ',' AlterExpressionColumnDataType )* ')' | 'FOREIGN' 'KEY' ColumnsNamesList 'REFERENCES' Table ColumnsNamesList? ( 'ON' ( 'DELETE' | 'UPDATE' ) Action )? ( 'ON' ( 'DELETE' | 'UPDATE' ) Action )? | 'CONSTRAINT' RelObjectName ( ( 'FOREIGN' 'KEY' ColumnsNamesList 'REFERENCES' Table ColumnsNamesList? ( 'ON' ( 'DELETE' | 'UPDATE' ) Action )? ( 'ON' ( 'DELETE' | 'UPDATE' ) Action )? | 'KEY' ColumnsNamesList ) AlterExpressionConstraintState | ( 'PRIMARY' 'KEY' | 'UNIQUE' ( 'KEY' | 'INDEX' )? ) ColumnsNamesList AlterExpressionConstraintState ( 'USING' RelObjectName )? | 'CHECK' ( '(' Expression ')' )* ) | RelObjectName 'COMMENT' S_CHAR_LITERAL )
-
           | 'CHANGE' 'COLUMN'? ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) AlterExpressionColumnDataType
-
           | 'DROP' ( ( ColumnsNamesList | 'COLUMN'? ( 'IF' 'EXISTS' )? ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) ) 'INVALIDATE'? ( 'CASCADE' 'CONSTRAINTS'? )? | 'INDEX' ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) | ( ( 'UNIQUE' | 'FOREIGN' 'KEY' ) ColumnsNamesList | 'PRIMARY' 'KEY' | 'CONSTRAINT' ( 'IF' 'EXISTS' )? ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) ) ( 'CASCADE' | 'RESTRICT' )? )
-
           | 'ALGORITHM' '='? RelObjectName
-
           | 'RENAME' ( 'COLUMN'? ( S_IDENTIFIER | S_QUOTED_IDENTIFIER ) )? 'TO' ( S_IDENTIFIER | S_QUOTED_IDENTIFIER )
-
           | 'COMMENT' S_CHAR_LITERAL
-
           | captureRest
-
- Referenced by: -
- - -====================================================================================================================== -Alter -====================================================================================================================== - - -.. raw:: html - - - - - - ALTER - - AlterTable - - AlterSession - - AlterView - - AlterSystemStatement - - AlterSequence - - captureRest - REPLACE - - AlterView - - captureRest - -
- - -
           | 'REPLACE' ( AlterView | captureRest )
-
- Referenced by: -
- - -====================================================================================================================== -AlterTable -====================================================================================================================== - - -.. raw:: html - - - - - - TABLE - - ONLY - - IF - - EXISTS - - Table - - AlterExpression - , - - -
- - -
         ::= 'TABLE' 'ONLY'? ( 'IF' 'EXISTS' )? Table AlterExpression ( ',' AlterExpression )*
-
- Referenced by: -
- - -====================================================================================================================== -AlterSession -====================================================================================================================== - - -.. raw:: html - - - - - - SESSION - - ADVISE - - COMMIT - - ROLLBACK - - NOTHING - - CLOSE - - DATABASE - - LINK - - ENABLE - - DISABLE - - COMMIT - - IN - - PROCEDURE - - GUARD - - PARALLEL - - DML - - DDL - - QUERY - - RESUMABLE - - FORCE - - PARALLEL - - DML - - DDL - - QUERY - - SET - - S_CHAR_LITERAL - - S_IDENTIFIER - = - - S_LONG - PARALLEL - - -
- - -
         ::= 'SESSION' ( 'ADVISE' ( 'COMMIT' | 'ROLLBACK' | 'NOTHING' ) | 'CLOSE' - 'DATABASE' 'LINK' | ( 'ENABLE' | 'DISABLE' ) ( 'COMMIT' 'IN' 'PROCEDURE' | 'GUARD' - | 'PARALLEL' ( 'DML' | 'DDL' | 'QUERY' ) | 'RESUMABLE' ) | 'FORCE' 'PARALLEL' ( 'DML' - | 'DDL' | 'QUERY' ) | 'SET' ) ( S_CHAR_LITERAL | S_IDENTIFIER | '=' | S_LONG | 'PARALLEL' )*
-
- Referenced by: -
- - -====================================================================================================================== -AlterSystemStatement -====================================================================================================================== - - -.. raw:: html - - - - - - SYSTEM - - ARCHIVE - - LOG - - CHECKPOINT - - DUMP - - ACTIVE - - SESSION - - HISTORY - - ENABLE - - DISABLE - - DISTRIBUTED RECOVERY - - RESTRICTED SESSION - - FLUSH - - DISCONNECT - - SESSION - - KILL SESSION - - SWITCH - - SUSPEND - - RESUME - - QUIESCE - - RESTRICTED - - UNQUIESCE - - SHUTDOWN - - REGISTER - - SET - - RESET - - captureRest - -
- - -
         ::= 'SYSTEM' ( 'ARCHIVE' 'LOG' | 'CHECKPOINT' | 'DUMP' 'ACTIVE' 'SESSION' - 'HISTORY' | ( 'ENABLE' | 'DISABLE' ) ( 'DISTRIBUTED RECOVERY' | 'RESTRICTED SESSION' - ) | 'FLUSH' | 'DISCONNECT' 'SESSION' | 'KILL SESSION' | 'SWITCH' | 'SUSPEND' | 'RESUME' - | 'QUIESCE' 'RESTRICTED' | 'UNQUIESCE' | 'SHUTDOWN' | 'REGISTER' | 'SET' | 'RESET' - ) captureRest
-
- Referenced by: -
- - -====================================================================================================================== -Wait -====================================================================================================================== - - -.. raw:: html - - - - - - WAIT - - S_LONG - -
- -
Wait     ::= 'WAIT' S_LONG
-
- Referenced by: -
- - -====================================================================================================================== -SavepointStatement -====================================================================================================================== - - -.. raw:: html - - - - - - SAVEPOINT - - S_IDENTIFIER - -
- - -
         ::= 'SAVEPOINT' S_IDENTIFIER
-
- Referenced by: -
- - -====================================================================================================================== -RollbackStatement -====================================================================================================================== - - -.. raw:: html - - - - - - ROLLBACK - - WORK - - TO - - SAVEPOINT - - S_IDENTIFIER - FORCE - - S_CHAR_LITERAL - -
- - -
         ::= 'ROLLBACK' 'WORK'? ( 'TO' 'SAVEPOINT'? S_IDENTIFIER | 'FORCE' S_CHAR_LITERAL )?
-
- Referenced by: -
- - -====================================================================================================================== -Comment -====================================================================================================================== - - -.. raw:: html - - - - - - COMMENT - - ON - - TABLE - - VIEW - - Table - COLUMN - - Column - IS - - S_CHAR_LITERAL - -
- -
Comment  ::= 'COMMENT' 'ON' ( ( 'TABLE' | 'VIEW' ) Table | 'COLUMN' Column ) 'IS' S_CHAR_LITERAL
-
- Referenced by: -
- - -====================================================================================================================== -Grant -====================================================================================================================== - - -.. raw:: html - - - - - - GRANT - - readGrantTypes - , - - ON - - RelObjectNameList - - S_IDENTIFIER - TO - - UsersList - -
- -
Grant    ::= 'GRANT' ( ( readGrantTypes ( ',' readGrantTypes )* )? 'ON' RelObjectNameList | S_IDENTIFIER ) 'TO' UsersList
-
- Referenced by: -
- - -====================================================================================================================== -UsersList -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectName - , - - ColumnsNamesListItem - -
- - -
         ::= RelObjectName ( ',' ColumnsNamesListItem )*
-
- Referenced by: -
- - -====================================================================================================================== -readGrantTypes -====================================================================================================================== - - -.. raw:: html - - - - - - K_SELECT - INSERT - - UPDATE - - DELETE - - EXECUTE - - ALTER - - DROP - - -
- - -
         ::= K_SELECT
-
           | 'INSERT'
-
           | 'UPDATE'
-
           | 'DELETE'
-
           | 'EXECUTE'
-
           | 'ALTER'
-
           | 'DROP'
-
- Referenced by: -
- - -====================================================================================================================== -Sequence -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameList - -
- - -
- Referenced by: -
- - -====================================================================================================================== -SequenceParameters -====================================================================================================================== - - -.. raw:: html - - - - - - INCREMENT - - BY - - START - - WITH - - MAXVALUE - - MINVALUE - - CACHE - - S_LONG - RESTART - - WITH - - S_LONG - NOMAXVALUE - - NOMINVALUE - - NOCYCLE - - CYCLE - - NOCACHE - - ORDER - - NOORDER - - KEEP - - NOKEEP - - SESSION - - GLOBAL - - -
- - -
         ::= ( ( 'INCREMENT' 'BY' | 'START' 'WITH' | 'MAXVALUE' | 'MINVALUE' | 'CACHE' - ) S_LONG | 'RESTART' ( 'WITH' S_LONG )? | 'NOMAXVALUE' | 'NOMINVALUE' | 'NOCYCLE' | 'CYCLE' | 'NOCACHE' | 'ORDER' | 'NOORDER' - | 'KEEP' | 'NOKEEP' | 'SESSION' | 'GLOBAL' )*
-
- Referenced by: -
- - -====================================================================================================================== -CreateSequence -====================================================================================================================== - - -.. raw:: html - - - - - - SEQUENCE - - Sequence - - SequenceParameters - -
- - -
         ::= 'SEQUENCE' Sequence SequenceParameters
-
- Referenced by: -
- - -====================================================================================================================== -AlterSequence -====================================================================================================================== - - -.. raw:: html - - - - - - SEQUENCE - - Sequence - - SequenceParameters - -
- - -
         ::= 'SEQUENCE' Sequence SequenceParameters
-
- Referenced by: -
- - -====================================================================================================================== -Create -====================================================================================================================== - - -.. raw:: html - - - - - - CREATE - - OR - - REPLACE - - CreateFunctionStatement - - CreateSchema - - CreateSequence - - CreateSynonym - - CreateTable - - CreateView - TRIGGER - - DOMAIN - - captureRest - - CreateIndex - -
- -
Create   ::= 'CREATE' ( 'OR' 'REPLACE' )? ( CreateFunctionStatement | CreateSchema | CreateSequence | CreateSynonym | CreateTable | CreateView | ( 'TRIGGER' | 'DOMAIN' )? captureRest | CreateIndex )
-
- Referenced by: -
- - -====================================================================================================================== -CreateFunctionStatement -====================================================================================================================== - - -.. raw:: html - - - - - - FUNCTION - - PROCEDURE - - captureFunctionBody - -
- - -
         ::= ( 'FUNCTION' | 'PROCEDURE' ) captureFunctionBody
-
- Referenced by: -
- - -====================================================================================================================== -CreateSynonym -====================================================================================================================== - - -.. raw:: html - - - - - - PUBLIC - - SYNONYM - - Synonym - FOR - - RelObjectNameList - -
- - -
         ::= 'PUBLIC'? 'SYNONYM' Synonym 'FOR' RelObjectNameList
-
- Referenced by: -
- - -====================================================================================================================== -Synonym -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameList - -
- - -
- Referenced by: -
- - -====================================================================================================================== -UnsupportedStatement -====================================================================================================================== - - -.. raw:: html - - - - - - captureUnsupportedStatementDeclaration - -
- - - -
- Referenced by: -
- - -====================================================================================================================== -IdentifierChain -====================================================================================================================== - - -.. raw:: html - - - - - - RelObjectNameExt2 - . - - -
- - -
         ::= RelObjectNameExt2 ( '.' RelObjectNameExt2 )*
-
- - -====================================================================================================================== -CharacterPrimary -====================================================================================================================== - - -.. raw:: html - - - - - - TranscodingFunction - - TrimFunction - -
- - -
         ::= TranscodingFunction
-
           | TrimFunction
-
- Referenced by: -
- - -====================================================================================================================== -TranscodingFunction -====================================================================================================================== - - -.. raw:: html - - - - - - CONVERT - - ( - - Expression - USING - - IdentifierChain - ) - - -
- - -
         ::= 'CONVERT' '(' Expression 'USING' IdentifierChain ')'
-
- Referenced by: -
- - -====================================================================================================================== -TrimFunction -====================================================================================================================== - - -.. raw:: html - - - - - - TRIM - - ( - - LEADING - - TRAILING - - BOTH - - Expression - , - - FROM - - Expression - ) - - -
- - -
         ::= 'TRIM' '(' ( 'LEADING' | 'TRAILING' | 'BOTH' )? Expression? ( ( ',' | 'FROM' ) Expression )? ')'
-
- Referenced by: -
- - -====================================================================================================================== -WHITESPACE -====================================================================================================================== - - -.. raw:: html - - - - - - - - [#x9] - - [#xD] - - [#xA] - - -
- - -
         ::= [ #x9#xD#xA]
-
- - -====================================================================================================================== -K_DATETIMELITERAL -====================================================================================================================== - - -.. raw:: html - - - - - - DATE - - TIME - - TIMESTAMP - - TIMESTAMPTZ - - -
- - -
         ::= 'DATE'
-
           | 'TIME'
-
           | 'TIMESTAMP'
-
           | 'TIMESTAMPTZ'
-
- - -====================================================================================================================== -K_DATE_LITERAL -====================================================================================================================== - - -.. raw:: html - - - - - - YEAR - - MONTH - - DAY - - HOUR - - MINUTE - - SECOND - - -
- - -
         ::= 'YEAR'
-
           | 'MONTH'
-
           | 'DAY'
-
           | 'HOUR'
-
           | 'MINUTE'
-
           | 'SECOND'
-
- - -====================================================================================================================== -K_ISOLATION -====================================================================================================================== - - -.. raw:: html - - - - - - UR - - RS - - RR - - CS - - -
- - -
         ::= 'UR'
-
           | 'RS'
-
           | 'RR'
-
           | 'CS'
-
- - -====================================================================================================================== -K_NEXTVAL -====================================================================================================================== - - -.. raw:: html - - - - - - NEXTVAL - - - - FOR - - NEXT - - - - VALUE - - - - FOR - - -
- - -
         ::= 'NEXTVAL' ( ' '+ 'FOR' )?
-
           | 'NEXT' ' '+ 'VALUE' ' '+ 'FOR'
-
- - -====================================================================================================================== -K_SELECT -====================================================================================================================== - - -.. raw:: html - - - - - - SELECT - - SEL - - -
- -
K_SELECT ::= 'SELECT'
-
           | 'SEL'
-
- - -====================================================================================================================== -K_TIME_KEY_EXPR -====================================================================================================================== - - -.. raw:: html - - - - - - CURRENT - - _ - - - - TIMESTAMP - - TIME - - DATE - - () - - -
- - -
         ::= 'CURRENT' ( '_' | ' '+ ) ( 'TIMESTAMP' | 'TIME' | 'DATE' ) '()'?
-
- - -====================================================================================================================== -K_STRING_FUNCTION_NAME -====================================================================================================================== - - -.. raw:: html - - - - - - SUBSTR - - SUBSTRING - - TRIM - - POSITION - - OVERLAY - - -
- - -
         ::= 'SUBSTR'
-
           | 'SUBSTRING'
-
           | 'TRIM'
-
           | 'POSITION'
-
           | 'OVERLAY'
-
- - -====================================================================================================================== -ST_SEMICOLON -====================================================================================================================== - - -.. raw:: html - - - - - - ; - - [#xA] - - / - - [#xA] - - [#xA] - - go - - -
- - -
         ::= ';'
-
           | #xA ( [/#xA] #xA | 'go' )
-
- Referenced by: -
- - -====================================================================================================================== -OP_GREATERTHANEQUALS -====================================================================================================================== - - -.. raw:: html - - - - - - > - - WHITESPACE - = - - -
- - -
         ::= '>' WHITESPACE* '='
-
- Referenced by: -
- - -====================================================================================================================== -OP_MINORTHANEQUALS -====================================================================================================================== - - -.. raw:: html - - - - - - < - - WHITESPACE - = - - -
- - -
         ::= '<' WHITESPACE* '='
-
- Referenced by: -
- - -====================================================================================================================== -OP_NOTEQUALSSTANDARD -====================================================================================================================== - - -.. raw:: html - - - - - - < - - WHITESPACE - > - - -
- - -
         ::= '<' WHITESPACE* '>'
-
- Referenced by: -
- - -====================================================================================================================== -OP_NOTEQUALSBANG -====================================================================================================================== - - -.. raw:: html - - - - - - ! - - WHITESPACE - = - - -
- - -
         ::= '!' WHITESPACE* '='
-
- Referenced by: -
- - -====================================================================================================================== -OP_CONCAT -====================================================================================================================== - - -.. raw:: html - - - - - - | - - WHITESPACE - | - - -
- - -
         ::= '|' WHITESPACE* '|'
-
- - -====================================================================================================================== -DT_ZONE -====================================================================================================================== - - -.. raw:: html - - - - - - K_DATETIMELITERAL - - WHITESPACE - ( - - S_LONG - ) - - WHITESPACE - WITH - - WITHOUT - - WHITESPACE - LOCAL - - WHITESPACE - TIME - - WHITESPACE - ZONE - - -
- -
DT_ZONE  ::= K_DATETIMELITERAL WHITESPACE* ( '(' S_LONG ')' )? WHITESPACE* ( 'WITH' | 'WITHOUT' ) WHITESPACE+ ( 'LOCAL' WHITESPACE+ )? 'TIME' WHITESPACE+ 'ZONE'
-
- - -====================================================================================================================== -S_DOUBLE -====================================================================================================================== - - -.. raw:: html - - - - - - S_LONG - . - - S_LONG - e - - E - - + - - [#x2D] - - S_LONG - - S_LONG - . - - e - - E - - + - - [#x2D] - - S_LONG - e - - E - - + - - [#x2D] - - S_LONG - -
- -
S_DOUBLE ::= S_LONG? '.' S_LONG ( [eE] [+#x2D]? S_LONG )?
-
           | S_LONG ( '.' ( [eE] [+#x2D]? S_LONG )? | [eE] [+#x2D]? S_LONG )
-
- - -====================================================================================================================== -S_LONG -====================================================================================================================== - - -.. raw:: html - - - - - - DIGIT - -
- -
S_LONG   ::= DIGIT+
-
- - -====================================================================================================================== -DIGIT -====================================================================================================================== - - -.. raw:: html - - - - - - [0-9] - - -
- -
DIGIT    ::= [0-9]
-
- Referenced by: -
- - -====================================================================================================================== -S_HEX -====================================================================================================================== - - -.. raw:: html - - - - - - x' - - HEX_VALUE - ' - - 0x - - HEX_VALUE - -
- -
S_HEX    ::= "x'" HEX_VALUE+ "'"
-
           | '0x' HEX_VALUE+
-
- - -====================================================================================================================== -HEX_VALUE -====================================================================================================================== - - -.. raw:: html - - - - - - [0-9] - - [A-F] - - -
- - -
         ::= [0-9A-F]
-
- Referenced by: -
- - -====================================================================================================================== -LINE_COMMENT -====================================================================================================================== - - -.. raw:: html - - - - - - -- - - // - - [^#xD#xA] - - -
- - -
         ::= ( '--' | '//' ) [^#xD#xA]*
-
- Not referenced by any. -
- - -====================================================================================================================== -MULTI_LINE_COMMENT -====================================================================================================================== - - -.. raw:: html - - - - - - /* - - [^*] - - * - - [^*] - - [^*/] - - / - - -
- - -
         ::= '/*' [^*]* '*' ( ( [^*/] [^*]* )? '*' )* '/'
-
- Not referenced by any. -
- - -====================================================================================================================== -S_IDENTIFIER -====================================================================================================================== - - -.. raw:: html - - - - - - LETTER - - PART_LETTER - -
- - -
         ::= LETTER PART_LETTER*
-
- - -====================================================================================================================== -LETTER -====================================================================================================================== - - -.. raw:: html - - - - - - UnicodeIdentifierStart - - Nd - $ - - _ - - [#x23] - - -
- - -
           | Nd
-
           | [$_#x23]
-
- Referenced by: -
- - -====================================================================================================================== -PART_LETTER -====================================================================================================================== - - -.. raw:: html - - - - - - UnicodeIdentifierStart - - UnicodeIdentifierExtend - $ - - _ - - @ - - [#x23] - - -
- - -
         ::= UnicodeIdentifierStart
-
           | UnicodeIdentifierExtend
-
           | [$_@#x23]
-
- Referenced by: -
- - -====================================================================================================================== -UnicodeIdentifierStart -====================================================================================================================== - - -.. raw:: html - - - - - - [#xB7] - - Ll - - Lm - - Lo - - Lt - - Lu - - Nl - - CJK - -
- - -
         ::= #xB7
-
           | Ll
-
           | Lm
-
           | Lo
-
           | Lt
-
           | Lu
-
           | Nl
-
           | CJK
-
- Referenced by: -
- - -====================================================================================================================== -Ll -====================================================================================================================== - - -.. raw:: html - - - - - - [a-z] - - [#xB5] - - [#xDF-#xF6] - - [#xF8-#xFF] - - [#x101] - - [#x103] - - [#x105] - - [#x107] - - [#x109] - - [#x10B] - - [#x10D] - - [#x10F] - - [#x111] - - [#x113] - - [#x115] - - [#x117] - - [#x119] - - [#x11B] - - [#x11D] - - [#x11F] - - [#x121] - - [#x123] - - [#x125] - - [#x127] - - [#x129] - - [#x12B] - - [#x12D] - - [#x12F] - - [#x131] - - [#x133] - - [#x135] - - [#x137-#x138] - - [#x13A] - - [#x13C] - - [#x13E] - - [#x140] - - [#x142] - - [#x144] - - [#x146] - - [#x148-#x149] - - [#x14B] - - [#x14D] - - [#x14F] - - [#x151] - - [#x153] - - [#x155] - - [#x157] - - [#x159] - - [#x15B] - - [#x15D] - - [#x15F] - - [#x161] - - [#x163] - - [#x165] - - [#x167] - - [#x169] - - [#x16B] - - [#x16D] - - [#x16F] - - [#x171] - - [#x173] - - [#x175] - - [#x177] - - [#x17A] - - [#x17C] - - [#x17E-#x180] - - [#x183] - - [#x185] - - [#x188] - - [#x18C-#x18D] - - [#x192] - - [#x195] - - [#x199-#x19B] - - [#x19E] - - [#x1A1] - - [#x1A3] - - [#x1A5] - - [#x1A8] - - [#x1AA-#x1AB] - - [#x1AD] - - [#x1B0] - - [#x1B4] - - [#x1B6] - - [#x1B9-#x1BA] - - [#x1BD-#x1BF] - - [#x1C6] - - [#x1C9] - - [#x1CC] - - [#x1CE] - - [#x1D0] - - [#x1D2] - - [#x1D4] - - [#x1D6] - - [#x1D8] - - [#x1DA] - - [#x1DC-#x1DD] - - [#x1DF] - - [#x1E1] - - [#x1E3] - - [#x1E5] - - [#x1E7] - - [#x1E9] - - [#x1EB] - - [#x1ED] - - [#x1EF-#x1F0] - - [#x1F3] - - [#x1F5] - - [#x1F9] - - [#x1FB] - - [#x1FD] - - [#x1FF] - - [#x201] - - [#x203] - - [#x205] - - [#x207] - - [#x209] - - [#x20B] - - [#x20D] - - [#x20F] - - [#x211] - - [#x213] - - [#x215] - - [#x217] - - [#x219] - - [#x21B] - - [#x21D] - - [#x21F] - - [#x221] - - [#x223] - - [#x225] - - [#x227] - - [#x229] - - [#x22B] - - [#x22D] - - [#x22F] - - [#x231] - - [#x233-#x239] - - [#x23C] - - [#x23F-#x240] - - [#x242] - - [#x247] - - [#x249] - - [#x24B] - - [#x24D] - - [#x24F-#x293] - - [#x295-#x2AF] - - [#x371] - - [#x373] - - [#x377] - - [#x37B-#x37D] - - [#x390] - - [#x3AC-#x3CE] - - [#x3D0-#x3D1] - - [#x3D5-#x3D7] - - [#x3D9] - - [#x3DB] - - [#x3DD] - - [#x3DF] - - [#x3E1] - - [#x3E3] - - [#x3E5] - - [#x3E7] - - [#x3E9] - - [#x3EB] - - [#x3ED] - - [#x3EF-#x3F3] - - [#x3F5] - - [#x3F8] - - [#x3FB-#x3FC] - - [#x430-#x45F] - - [#x461] - - [#x463] - - [#x465] - - [#x467] - - [#x469] - - [#x46B] - - [#x46D] - - [#x46F] - - [#x471] - - [#x473] - - [#x475] - - [#x477] - - [#x479] - - [#x47B] - - [#x47D] - - [#x47F] - - [#x481] - - [#x48B] - - [#x48D] - - [#x48F] - - [#x491] - - [#x493] - - [#x495] - - [#x497] - - [#x499] - - [#x49B] - - [#x49D] - - [#x49F] - - [#x4A1] - - [#x4A3] - - [#x4A5] - - [#x4A7] - - [#x4A9] - - [#x4AB] - - [#x4AD] - - [#x4AF] - - [#x4B1] - - [#x4B3] - - [#x4B5] - - [#x4B7] - - [#x4B9] - - [#x4BB] - - [#x4BD] - - [#x4BF] - - [#x4C2] - - [#x4C4] - - [#x4C6] - - [#x4C8] - - [#x4CA] - - [#x4CC] - - [#x4CE-#x4CF] - - [#x4D1] - - [#x4D3] - - [#x4D5] - - [#x4D7] - - [#x4D9] - - [#x4DB] - - [#x4DD] - - [#x4DF] - - [#x4E1] - - [#x4E3] - - [#x4E5] - - [#x4E7] - - [#x4E9] - - [#x4EB] - - [#x4ED] - - [#x4EF] - - [#x4F1] - - [#x4F3] - - [#x4F5] - - [#x4F7] - - [#x4F9] - - [#x4FB] - - [#x4FD] - - [#x4FF] - - [#x501] - - [#x503] - - [#x505] - - [#x507] - - [#x509] - - [#x50B] - - [#x50D] - - [#x50F] - - [#x511] - - [#x513] - - [#x515] - - [#x517] - - [#x519] - - [#x51B] - - [#x51D] - - [#x51F] - - [#x521] - - [#x523] - - [#x525] - - [#x527] - - [#x529] - - [#x52B] - - [#x52D] - - [#x52F] - - [#x560-#x588] - - [#x10D0-#x10FA] - - [#x10FD-#x10FF] - - [#x13F8-#x13FD] - - [#x1C80-#x1C88] - - [#x1D00-#x1D2B] - - [#x1D6B-#x1D77] - - [#x1D79-#x1D9A] - - [#x1E01] - - [#x1E03] - - [#x1E05] - - [#x1E07] - - [#x1E09] - - [#x1E0B] - - [#x1E0D] - - [#x1E0F] - - [#x1E11] - - [#x1E13] - - [#x1E15] - - [#x1E17] - - [#x1E19] - - [#x1E1B] - - [#x1E1D] - - [#x1E1F] - - [#x1E21] - - [#x1E23] - - [#x1E25] - - [#x1E27] - - [#x1E29] - - [#x1E2B] - - [#x1E2D] - - [#x1E2F] - - [#x1E31] - - [#x1E33] - - [#x1E35] - - [#x1E37] - - [#x1E39] - - [#x1E3B] - - [#x1E3D] - - [#x1E3F] - - [#x1E41] - - [#x1E43] - - [#x1E45] - - [#x1E47] - - [#x1E49] - - [#x1E4B] - - [#x1E4D] - - [#x1E4F] - - [#x1E51] - - [#x1E53] - - [#x1E55] - - [#x1E57] - - [#x1E59] - - [#x1E5B] - - [#x1E5D] - - [#x1E5F] - - [#x1E61] - - [#x1E63] - - [#x1E65] - - [#x1E67] - - [#x1E69] - - [#x1E6B] - - [#x1E6D] - - [#x1E6F] - - [#x1E71] - - [#x1E73] - - [#x1E75] - - [#x1E77] - - [#x1E79] - - [#x1E7B] - - [#x1E7D] - - [#x1E7F] - - [#x1E81] - - [#x1E83] - - [#x1E85] - - [#x1E87] - - [#x1E89] - - [#x1E8B] - - [#x1E8D] - - [#x1E8F] - - [#x1E91] - - [#x1E93] - - [#x1E95-#x1E9D] - - [#x1E9F] - - [#x1EA1] - - [#x1EA3] - - [#x1EA5] - - [#x1EA7] - - [#x1EA9] - - [#x1EAB] - - [#x1EAD] - - [#x1EAF] - - [#x1EB1] - - [#x1EB3] - - [#x1EB5] - - [#x1EB7] - - [#x1EB9] - - [#x1EBB] - - [#x1EBD] - - [#x1EBF] - - [#x1EC1] - - [#x1EC3] - - [#x1EC5] - - [#x1EC7] - - [#x1EC9] - - [#x1ECB] - - [#x1ECD] - - [#x1ECF] - - [#x1ED1] - - [#x1ED3] - - [#x1ED5] - - [#x1ED7] - - [#x1ED9] - - [#x1EDB] - - [#x1EDD] - - [#x1EDF] - - [#x1EE1] - - [#x1EE3] - - [#x1EE5] - - [#x1EE7] - - [#x1EE9] - - [#x1EEB] - - [#x1EED] - - [#x1EEF] - - [#x1EF1] - - [#x1EF3] - - [#x1EF5] - - [#x1EF7] - - [#x1EF9] - - [#x1EFB] - - [#x1EFD] - - [#x1EFF-#x1F07] - - [#x1F10-#x1F15] - - [#x1F20-#x1F27] - - [#x1F30-#x1F37] - - [#x1F40-#x1F45] - - [#x1F50-#x1F57] - - [#x1F60-#x1F67] - - [#x1F70-#x1F7D] - - [#x1F80-#x1F87] - - [#x1F90-#x1F97] - - [#x1FA0-#x1FA7] - - [#x1FB0-#x1FB4] - - [#x1FB6-#x1FB7] - - [#x1FBE] - - [#x1FC2-#x1FC4] - - [#x1FC6-#x1FC7] - - [#x1FD0-#x1FD3] - - [#x1FD6-#x1FD7] - - [#x1FE0-#x1FE7] - - [#x1FF2-#x1FF4] - - [#x1FF6-#x1FF7] - - [#x210A] - - [#x210E-#x210F] - - [#x2113] - - [#x212F] - - [#x2134] - - [#x2139] - - [#x213C-#x213D] - - [#x2146-#x2149] - - [#x214E] - - [#x2184] - - [#x2C30-#x2C5F] - - [#x2C61] - - [#x2C65-#x2C66] - - [#x2C68] - - [#x2C6A] - - [#x2C6C] - - [#x2C71] - - [#x2C73-#x2C74] - - [#x2C76-#x2C7B] - - [#x2C81] - - [#x2C83] - - [#x2C85] - - [#x2C87] - - [#x2C89] - - [#x2C8B] - - [#x2C8D] - - [#x2C8F] - - [#x2C91] - - [#x2C93] - - [#x2C95] - - [#x2C97] - - [#x2C99] - - [#x2C9B] - - [#x2C9D] - - [#x2C9F] - - [#x2CA1] - - [#x2CA3] - - [#x2CA5] - - [#x2CA7] - - [#x2CA9] - - [#x2CAB] - - [#x2CAD] - - [#x2CAF] - - [#x2CB1] - - [#x2CB3] - - [#x2CB5] - - [#x2CB7] - - [#x2CB9] - - [#x2CBB] - - [#x2CBD] - - [#x2CBF] - - [#x2CC1] - - [#x2CC3] - - [#x2CC5] - - [#x2CC7] - - [#x2CC9] - - [#x2CCB] - - [#x2CCD] - - [#x2CCF] - - [#x2CD1] - - [#x2CD3] - - [#x2CD5] - - [#x2CD7] - - [#x2CD9] - - [#x2CDB] - - [#x2CDD] - - [#x2CDF] - - [#x2CE1] - - [#x2CE3-#x2CE4] - - [#x2CEC] - - [#x2CEE] - - [#x2CF3] - - [#x2D00-#x2D25] - - [#x2D27] - - [#x2D2D] - - [#xA641] - - [#xA643] - - [#xA645] - - [#xA647] - - [#xA649] - - [#xA64B] - - [#xA64D] - - [#xA64F] - - [#xA651] - - [#xA653] - - [#xA655] - - [#xA657] - - [#xA659] - - [#xA65B] - - [#xA65D] - - [#xA65F] - - [#xA661] - - [#xA663] - - [#xA665] - - [#xA667] - - [#xA669] - - [#xA66B] - - [#xA66D] - - [#xA681] - - [#xA683] - - [#xA685] - - [#xA687] - - [#xA689] - - [#xA68B] - - [#xA68D] - - [#xA68F] - - [#xA691] - - [#xA693] - - [#xA695] - - [#xA697] - - [#xA699] - - [#xA69B] - - [#xA723] - - [#xA725] - - [#xA727] - - [#xA729] - - [#xA72B] - - [#xA72D] - - [#xA72F-#xA731] - - [#xA733] - - [#xA735] - - [#xA737] - - [#xA739] - - [#xA73B] - - [#xA73D] - - [#xA73F] - - [#xA741] - - [#xA743] - - [#xA745] - - [#xA747] - - [#xA749] - - [#xA74B] - - [#xA74D] - - [#xA74F] - - [#xA751] - - [#xA753] - - [#xA755] - - [#xA757] - - [#xA759] - - [#xA75B] - - [#xA75D] - - [#xA75F] - - [#xA761] - - [#xA763] - - [#xA765] - - [#xA767] - - [#xA769] - - [#xA76B] - - [#xA76D] - - [#xA76F] - - [#xA771-#xA778] - - [#xA77A] - - [#xA77C] - - [#xA77F] - - [#xA781] - - [#xA783] - - [#xA785] - - [#xA787] - - [#xA78C] - - [#xA78E] - - [#xA791] - - [#xA793-#xA795] - - [#xA797] - - [#xA799] - - [#xA79B] - - [#xA79D] - - [#xA79F] - - [#xA7A1] - - [#xA7A3] - - [#xA7A5] - - [#xA7A7] - - [#xA7A9] - - [#xA7AF] - - [#xA7B5] - - [#xA7B7] - - [#xA7B9] - - [#xA7BB] - - [#xA7BD] - - [#xA7BF] - - [#xA7C1] - - [#xA7C3] - - [#xA7C8] - - [#xA7CA] - - [#xA7D1] - - [#xA7D3] - - [#xA7D5] - - [#xA7D7] - - [#xA7D9] - - [#xA7F6] - - [#xA7FA] - - [#xAB30-#xAB5A] - - [#xAB60-#xAB68] - - [#xAB70-#xABBF] - - [#xFB00-#xFB06] - - [#xFB13-#xFB17] - - [#xFF41-#xFF5A] - - -
- -
Ll       ::= [a-z#xB5#xDF-#xF6#xF8-#xFF#x101#x103#x105#x107#x109#x10B#x10D#x10F#x111#x113#x115#x117#x119#x11B#x11D#x11F#x121#x123#x125#x127#x129#x12B#x12D#x12F#x131#x133#x135#x137-#x138#x13A#x13C#x13E#x140#x142#x144#x146#x148-#x149#x14B#x14D#x14F#x151#x153#x155#x157#x159#x15B#x15D#x15F#x161#x163#x165#x167#x169#x16B#x16D#x16F#x171#x173#x175#x177#x17A#x17C#x17E-#x180#x183#x185#x188#x18C-#x18D#x192#x195#x199-#x19B#x19E#x1A1#x1A3#x1A5#x1A8#x1AA-#x1AB#x1AD#x1B0#x1B4#x1B6#x1B9-#x1BA#x1BD-#x1BF#x1C6#x1C9#x1CC#x1CE#x1D0#x1D2#x1D4#x1D6#x1D8#x1DA#x1DC-#x1DD#x1DF#x1E1#x1E3#x1E5#x1E7#x1E9#x1EB#x1ED#x1EF-#x1F0#x1F3#x1F5#x1F9#x1FB#x1FD#x1FF#x201#x203#x205#x207#x209#x20B#x20D#x20F#x211#x213#x215#x217#x219#x21B#x21D#x21F#x221#x223#x225#x227#x229#x22B#x22D#x22F#x231#x233-#x239#x23C#x23F-#x240#x242#x247#x249#x24B#x24D#x24F-#x293#x295-#x2AF#x371#x373#x377#x37B-#x37D#x390#x3AC-#x3CE#x3D0-#x3D1#x3D5-#x3D7#x3D9#x3DB#x3DD#x3DF#x3E1#x3E3#x3E5#x3E7#x3E9#x3EB#x3ED#x3EF-#x3F3#x3F5#x3F8#x3FB-#x3FC#x430-#x45F#x461#x463#x465#x467#x469#x46B#x46D#x46F#x471#x473#x475#x477#x479#x47B#x47D#x47F#x481#x48B#x48D#x48F#x491#x493#x495#x497#x499#x49B#x49D#x49F#x4A1#x4A3#x4A5#x4A7#x4A9#x4AB#x4AD#x4AF#x4B1#x4B3#x4B5#x4B7#x4B9#x4BB#x4BD#x4BF#x4C2#x4C4#x4C6#x4C8#x4CA#x4CC#x4CE-#x4CF#x4D1#x4D3#x4D5#x4D7#x4D9#x4DB#x4DD#x4DF#x4E1#x4E3#x4E5#x4E7#x4E9#x4EB#x4ED#x4EF#x4F1#x4F3#x4F5#x4F7#x4F9#x4FB#x4FD#x4FF#x501#x503#x505#x507#x509#x50B#x50D#x50F#x511#x513#x515#x517#x519#x51B#x51D#x51F#x521#x523#x525#x527#x529#x52B#x52D#x52F#x560-#x588#x10D0-#x10FA#x10FD-#x10FF#x13F8-#x13FD#x1C80-#x1C88#x1D00-#x1D2B#x1D6B-#x1D77#x1D79-#x1D9A#x1E01#x1E03#x1E05#x1E07#x1E09#x1E0B#x1E0D#x1E0F#x1E11#x1E13#x1E15#x1E17#x1E19#x1E1B#x1E1D#x1E1F#x1E21#x1E23#x1E25#x1E27#x1E29#x1E2B#x1E2D#x1E2F#x1E31#x1E33#x1E35#x1E37#x1E39#x1E3B#x1E3D#x1E3F#x1E41#x1E43#x1E45#x1E47#x1E49#x1E4B#x1E4D#x1E4F#x1E51#x1E53#x1E55#x1E57#x1E59#x1E5B#x1E5D#x1E5F#x1E61#x1E63#x1E65#x1E67#x1E69#x1E6B#x1E6D#x1E6F#x1E71#x1E73#x1E75#x1E77#x1E79#x1E7B#x1E7D#x1E7F#x1E81#x1E83#x1E85#x1E87#x1E89#x1E8B#x1E8D#x1E8F#x1E91#x1E93#x1E95-#x1E9D#x1E9F#x1EA1#x1EA3#x1EA5#x1EA7#x1EA9#x1EAB#x1EAD#x1EAF#x1EB1#x1EB3#x1EB5#x1EB7#x1EB9#x1EBB#x1EBD#x1EBF#x1EC1#x1EC3#x1EC5#x1EC7#x1EC9#x1ECB#x1ECD#x1ECF#x1ED1#x1ED3#x1ED5#x1ED7#x1ED9#x1EDB#x1EDD#x1EDF#x1EE1#x1EE3#x1EE5#x1EE7#x1EE9#x1EEB#x1EED#x1EEF#x1EF1#x1EF3#x1EF5#x1EF7#x1EF9#x1EFB#x1EFD#x1EFF-#x1F07#x1F10-#x1F15#x1F20-#x1F27#x1F30-#x1F37#x1F40-#x1F45#x1F50-#x1F57#x1F60-#x1F67#x1F70-#x1F7D#x1F80-#x1F87#x1F90-#x1F97#x1FA0-#x1FA7#x1FB0-#x1FB4#x1FB6-#x1FB7#x1FBE#x1FC2-#x1FC4#x1FC6-#x1FC7#x1FD0-#x1FD3#x1FD6-#x1FD7#x1FE0-#x1FE7#x1FF2-#x1FF4#x1FF6-#x1FF7#x210A#x210E-#x210F#x2113#x212F#x2134#x2139#x213C-#x213D#x2146-#x2149#x214E#x2184#x2C30-#x2C5F#x2C61#x2C65-#x2C66#x2C68#x2C6A#x2C6C#x2C71#x2C73-#x2C74#x2C76-#x2C7B#x2C81#x2C83#x2C85#x2C87#x2C89#x2C8B#x2C8D#x2C8F#x2C91#x2C93#x2C95#x2C97#x2C99#x2C9B#x2C9D#x2C9F#x2CA1#x2CA3#x2CA5#x2CA7#x2CA9#x2CAB#x2CAD#x2CAF#x2CB1#x2CB3#x2CB5#x2CB7#x2CB9#x2CBB#x2CBD#x2CBF#x2CC1#x2CC3#x2CC5#x2CC7#x2CC9#x2CCB#x2CCD#x2CCF#x2CD1#x2CD3#x2CD5#x2CD7#x2CD9#x2CDB#x2CDD#x2CDF#x2CE1#x2CE3-#x2CE4#x2CEC#x2CEE#x2CF3#x2D00-#x2D25#x2D27#x2D2D#xA641#xA643#xA645#xA647#xA649#xA64B#xA64D#xA64F#xA651#xA653#xA655#xA657#xA659#xA65B#xA65D#xA65F#xA661#xA663#xA665#xA667#xA669#xA66B#xA66D#xA681#xA683#xA685#xA687#xA689#xA68B#xA68D#xA68F#xA691#xA693#xA695#xA697#xA699#xA69B#xA723#xA725#xA727#xA729#xA72B#xA72D#xA72F-#xA731#xA733#xA735#xA737#xA739#xA73B#xA73D#xA73F#xA741#xA743#xA745#xA747#xA749#xA74B#xA74D#xA74F#xA751#xA753#xA755#xA757#xA759#xA75B#xA75D#xA75F#xA761#xA763#xA765#xA767#xA769#xA76B#xA76D#xA76F#xA771-#xA778#xA77A#xA77C#xA77F#xA781#xA783#xA785#xA787#xA78C#xA78E#xA791#xA793-#xA795#xA797#xA799#xA79B#xA79D#xA79F#xA7A1#xA7A3#xA7A5#xA7A7#xA7A9#xA7AF#xA7B5#xA7B7#xA7B9#xA7BB#xA7BD#xA7BF#xA7C1#xA7C3#xA7C8#xA7CA#xA7D1#xA7D3#xA7D5#xA7D7#xA7D9#xA7F6#xA7FA#xAB30-#xAB5A#xAB60-#xAB68#xAB70-#xABBF#xFB00-#xFB06#xFB13-#xFB17#xFF41-#xFF5A]
-
- Referenced by: -
- - -====================================================================================================================== -Lm -====================================================================================================================== - - -.. raw:: html - - - - - - [#x2B0-#x2C1] - - [#x2C6-#x2D1] - - [#x2E0-#x2E4] - - [#x2EC] - - [#x2EE] - - [#x374] - - [#x37A] - - [#x559] - - [#x640] - - [#x6E5-#x6E6] - - [#x7F4-#x7F5] - - [#x7FA] - - [#x81A] - - [#x824] - - [#x828] - - [#x8C9] - - [#x971] - - [#xE46] - - [#xEC6] - - [#x10FC] - - [#x17D7] - - [#x1843] - - [#x1AA7] - - [#x1C78-#x1C7D] - - [#x1D2C-#x1D6A] - - [#x1D78] - - [#x1D9B-#x1DBF] - - [#x2071] - - [#x207F] - - [#x2090-#x209C] - - [#x2C7C-#x2C7D] - - [#x2D6F] - - [#x2E2F] - - [#x3005] - - [#x3031-#x3035] - - [#x303B] - - [#x309D-#x309E] - - [#x30FC-#x30FE] - - [#xA015] - - [#xA4F8-#xA4FD] - - [#xA60C] - - [#xA67F] - - [#xA69C-#xA69D] - - [#xA717-#xA71F] - - [#xA770] - - [#xA788] - - [#xA7F2-#xA7F4] - - [#xA7F8-#xA7F9] - - [#xA9CF] - - [#xA9E6] - - [#xAA70] - - [#xAADD] - - [#xAAF3-#xAAF4] - - [#xAB5C-#xAB5F] - - [#xAB69] - - [#xFF70] - - [#xFF9E-#xFF9F] - - -
- -
Lm       ::= [#x2B0-#x2C1#x2C6-#x2D1#x2E0-#x2E4#x2EC#x2EE#x374#x37A#x559#x640#x6E5-#x6E6#x7F4-#x7F5#x7FA#x81A#x824#x828#x8C9#x971#xE46#xEC6#x10FC#x17D7#x1843#x1AA7#x1C78-#x1C7D#x1D2C-#x1D6A#x1D78#x1D9B-#x1DBF#x2071#x207F#x2090-#x209C#x2C7C-#x2C7D#x2D6F#x2E2F#x3005#x3031-#x3035#x303B#x309D-#x309E#x30FC-#x30FE#xA015#xA4F8-#xA4FD#xA60C#xA67F#xA69C-#xA69D#xA717-#xA71F#xA770#xA788#xA7F2-#xA7F4#xA7F8-#xA7F9#xA9CF#xA9E6#xAA70#xAADD#xAAF3-#xAAF4#xAB5C-#xAB5F#xAB69#xFF70#xFF9E-#xFF9F]
-
- Referenced by: -
- - -====================================================================================================================== -Lo -====================================================================================================================== - - -.. raw:: html - - - - - - [#xAA] - - [#xBA] - - [#x1BB] - - [#x1C0-#x1C3] - - [#x294] - - [#x5D0-#x5EA] - - [#x5EF-#x5F2] - - [#x620-#x63F] - - [#x641-#x64A] - - [#x66E-#x66F] - - [#x671-#x6D3] - - [#x6D5] - - [#x6EE-#x6EF] - - [#x6FA-#x6FC] - - [#x6FF] - - [#x710] - - [#x712-#x72F] - - [#x74D-#x7A5] - - [#x7B1] - - [#x7CA-#x7EA] - - [#x800-#x815] - - [#x840-#x858] - - [#x860-#x86A] - - [#x870-#x887] - - [#x889-#x88E] - - [#x8A0-#x8C8] - - [#x904-#x939] - - [#x93D] - - [#x950] - - [#x958-#x961] - - [#x972-#x980] - - [#x985-#x98C] - - [#x98F-#x990] - - [#x993-#x9A8] - - [#x9AA-#x9B0] - - [#x9B2] - - [#x9B6-#x9B9] - - [#x9BD] - - [#x9CE] - - [#x9DC-#x9DD] - - [#x9DF-#x9E1] - - [#x9F0-#x9F1] - - [#x9FC] - - [#xA05-#xA0A] - - [#xA0F-#xA10] - - [#xA13-#xA28] - - [#xA2A-#xA30] - - [#xA32-#xA33] - - [#xA35-#xA36] - - [#xA38-#xA39] - - [#xA59-#xA5C] - - [#xA5E] - - [#xA72-#xA74] - - [#xA85-#xA8D] - - [#xA8F-#xA91] - - [#xA93-#xAA8] - - [#xAAA-#xAB0] - - [#xAB2-#xAB3] - - [#xAB5-#xAB9] - - [#xABD] - - [#xAD0] - - [#xAE0-#xAE1] - - [#xAF9] - - [#xB05-#xB0C] - - [#xB0F-#xB10] - - [#xB13-#xB28] - - [#xB2A-#xB30] - - [#xB32-#xB33] - - [#xB35-#xB39] - - [#xB3D] - - [#xB5C-#xB5D] - - [#xB5F-#xB61] - - [#xB71] - - [#xB83] - - [#xB85-#xB8A] - - [#xB8E-#xB90] - - [#xB92-#xB95] - - [#xB99-#xB9A] - - [#xB9C] - - [#xB9E-#xB9F] - - [#xBA3-#xBA4] - - [#xBA8-#xBAA] - - [#xBAE-#xBB9] - - [#xBD0] - - [#xC05-#xC0C] - - [#xC0E-#xC10] - - [#xC12-#xC28] - - [#xC2A-#xC39] - - [#xC3D] - - [#xC58-#xC5A] - - [#xC5D] - - [#xC60-#xC61] - - [#xC80] - - [#xC85-#xC8C] - - [#xC8E-#xC90] - - [#xC92-#xCA8] - - [#xCAA-#xCB3] - - [#xCB5-#xCB9] - - [#xCBD] - - [#xCDD-#xCDE] - - [#xCE0-#xCE1] - - [#xCF1-#xCF2] - - [#xD04-#xD0C] - - [#xD0E-#xD10] - - [#xD12-#xD3A] - - [#xD3D] - - [#xD4E] - - [#xD54-#xD56] - - [#xD5F-#xD61] - - [#xD7A-#xD7F] - - [#xD85-#xD96] - - [#xD9A-#xDB1] - - [#xDB3-#xDBB] - - [#xDBD] - - [#xDC0-#xDC6] - - [#xE01-#xE30] - - [#xE32-#xE33] - - [#xE40-#xE45] - - [#xE81-#xE82] - - [#xE84] - - [#xE86-#xE8A] - - [#xE8C-#xEA3] - - [#xEA5] - - [#xEA7-#xEB0] - - [#xEB2-#xEB3] - - [#xEBD] - - [#xEC0-#xEC4] - - [#xEDC-#xEDF] - - [#xF00] - - [#xF40-#xF47] - - [#xF49-#xF6C] - - [#xF88-#xF8C] - - [#x1000-#x102A] - - [#x103F] - - [#x1050-#x1055] - - [#x105A-#x105D] - - [#x1061] - - [#x1065-#x1066] - - [#x106E-#x1070] - - [#x1075-#x1081] - - [#x108E] - - [#x1100-#x1248] - - [#x124A-#x124D] - - [#x1250-#x1256] - - [#x1258] - - [#x125A-#x125D] - - [#x1260-#x1288] - - [#x128A-#x128D] - - [#x1290-#x12B0] - - [#x12B2-#x12B5] - - [#x12B8-#x12BE] - - [#x12C0] - - [#x12C2-#x12C5] - - [#x12C8-#x12D6] - - [#x12D8-#x1310] - - [#x1312-#x1315] - - [#x1318-#x135A] - - [#x1380-#x138F] - - [#x1401-#x166C] - - [#x166F-#x167F] - - [#x1681-#x169A] - - [#x16A0-#x16EA] - - [#x16F1-#x16F8] - - [#x1700-#x1711] - - [#x171F-#x1731] - - [#x1740-#x1751] - - [#x1760-#x176C] - - [#x176E-#x1770] - - [#x1780-#x17B3] - - [#x17DC] - - [#x1820-#x1842] - - [#x1844-#x1878] - - [#x1880-#x1884] - - [#x1887-#x18A8] - - [#x18AA] - - [#x18B0-#x18F5] - - [#x1900-#x191E] - - [#x1950-#x196D] - - [#x1970-#x1974] - - [#x1980-#x19AB] - - [#x19B0-#x19C9] - - [#x1A00-#x1A16] - - [#x1A20-#x1A54] - - [#x1B05-#x1B33] - - [#x1B45-#x1B4C] - - [#x1B83-#x1BA0] - - [#x1BAE-#x1BAF] - - [#x1BBA-#x1BE5] - - [#x1C00-#x1C23] - - [#x1C4D-#x1C4F] - - [#x1C5A-#x1C77] - - [#x1CE9-#x1CEC] - - [#x1CEE-#x1CF3] - - [#x1CF5-#x1CF6] - - [#x1CFA] - - [#x2135-#x2138] - - [#x2D30-#x2D67] - - [#x2D80-#x2D96] - - [#x2DA0-#x2DA6] - - [#x2DA8-#x2DAE] - - [#x2DB0-#x2DB6] - - [#x2DB8-#x2DBE] - - [#x2DC0-#x2DC6] - - [#x2DC8-#x2DCE] - - [#x2DD0-#x2DD6] - - [#x2DD8-#x2DDE] - - [#x3006] - - [#x303C] - - [#x3041-#x3096] - - [#x309F] - - [#x30A1-#x30FA] - - [#x30FF] - - [#x3105-#x312F] - - [#x3131-#x318E] - - [#x31A0-#x31BF] - - [#x31F0-#x31FF] - - [#x4DBF] - - [#x9FFF-#xA014] - - [#xA016-#xA48C] - - [#xA4D0-#xA4F7] - - [#xA500-#xA60B] - - [#xA610-#xA61F] - - [#xA62A-#xA62B] - - [#xA66E] - - [#xA6A0-#xA6E5] - - [#xA78F] - - [#xA7F7] - - [#xA7FB-#xA801] - - [#xA803-#xA805] - - [#xA807-#xA80A] - - [#xA80C-#xA822] - - [#xA840-#xA873] - - [#xA882-#xA8B3] - - [#xA8F2-#xA8F7] - - [#xA8FB] - - [#xA8FD-#xA8FE] - - [#xA90A-#xA925] - - [#xA930-#xA946] - - [#xA960-#xA97C] - - [#xA984-#xA9B2] - - [#xA9E0-#xA9E4] - - [#xA9E7-#xA9EF] - - [#xA9FA-#xA9FE] - - [#xAA00-#xAA28] - - [#xAA40-#xAA42] - - [#xAA44-#xAA4B] - - [#xAA60-#xAA6F] - - [#xAA71-#xAA76] - - [#xAA7A] - - [#xAA7E-#xAAAF] - - [#xAAB1] - - [#xAAB5-#xAAB6] - - [#xAAB9-#xAABD] - - [#xAAC0] - - [#xAAC2] - - [#xAADB-#xAADC] - - [#xAAE0-#xAAEA] - - [#xAAF2] - - [#xAB01-#xAB06] - - [#xAB09-#xAB0E] - - [#xAB11-#xAB16] - - [#xAB20-#xAB26] - - [#xAB28-#xAB2E] - - [#xABC0-#xABE2] - - [#xD7A3] - - [#xD7B0-#xD7C6] - - [#xD7CB-#xD7FB] - - [#xF900-#xFA6D] - - [#xFA70-#xFAD9] - - [#xFB1D] - - [#xFB1F-#xFB28] - - [#xFB2A-#xFB36] - - [#xFB38-#xFB3C] - - [#xFB3E] - - [#xFB40-#xFB41] - - [#xFB43-#xFB44] - - [#xFB46-#xFBB1] - - [#xFBD3-#xFD3D] - - [#xFD50-#xFD8F] - - [#xFD92-#xFDC7] - - [#xFDF0-#xFDFB] - - [#xFE70-#xFE74] - - [#xFE76-#xFEFC] - - [#xFF66-#xFF6F] - - [#xFF71-#xFF9D] - - [#xFFA0-#xFFBE] - - [#xFFC2-#xFFC7] - - [#xFFCA-#xFFCF] - - [#xFFD2-#xFFD7] - - [#xFFDA-#xFFDC] - - -
- -
Lo       ::= [#xAA#xBA#x1BB#x1C0-#x1C3#x294#x5D0-#x5EA#x5EF-#x5F2#x620-#x63F#x641-#x64A#x66E-#x66F#x671-#x6D3#x6D5#x6EE-#x6EF#x6FA-#x6FC#x6FF#x710#x712-#x72F#x74D-#x7A5#x7B1#x7CA-#x7EA#x800-#x815#x840-#x858#x860-#x86A#x870-#x887#x889-#x88E#x8A0-#x8C8#x904-#x939#x93D#x950#x958-#x961#x972-#x980#x985-#x98C#x98F-#x990#x993-#x9A8#x9AA-#x9B0#x9B2#x9B6-#x9B9#x9BD#x9CE#x9DC-#x9DD#x9DF-#x9E1#x9F0-#x9F1#x9FC#xA05-#xA0A#xA0F-#xA10#xA13-#xA28#xA2A-#xA30#xA32-#xA33#xA35-#xA36#xA38-#xA39#xA59-#xA5C#xA5E#xA72-#xA74#xA85-#xA8D#xA8F-#xA91#xA93-#xAA8#xAAA-#xAB0#xAB2-#xAB3#xAB5-#xAB9#xABD#xAD0#xAE0-#xAE1#xAF9#xB05-#xB0C#xB0F-#xB10#xB13-#xB28#xB2A-#xB30#xB32-#xB33#xB35-#xB39#xB3D#xB5C-#xB5D#xB5F-#xB61#xB71#xB83#xB85-#xB8A#xB8E-#xB90#xB92-#xB95#xB99-#xB9A#xB9C#xB9E-#xB9F#xBA3-#xBA4#xBA8-#xBAA#xBAE-#xBB9#xBD0#xC05-#xC0C#xC0E-#xC10#xC12-#xC28#xC2A-#xC39#xC3D#xC58-#xC5A#xC5D#xC60-#xC61#xC80#xC85-#xC8C#xC8E-#xC90#xC92-#xCA8#xCAA-#xCB3#xCB5-#xCB9#xCBD#xCDD-#xCDE#xCE0-#xCE1#xCF1-#xCF2#xD04-#xD0C#xD0E-#xD10#xD12-#xD3A#xD3D#xD4E#xD54-#xD56#xD5F-#xD61#xD7A-#xD7F#xD85-#xD96#xD9A-#xDB1#xDB3-#xDBB#xDBD#xDC0-#xDC6#xE01-#xE30#xE32-#xE33#xE40-#xE45#xE81-#xE82#xE84#xE86-#xE8A#xE8C-#xEA3#xEA5#xEA7-#xEB0#xEB2-#xEB3#xEBD#xEC0-#xEC4#xEDC-#xEDF#xF00#xF40-#xF47#xF49-#xF6C#xF88-#xF8C#x1000-#x102A#x103F#x1050-#x1055#x105A-#x105D#x1061#x1065-#x1066#x106E-#x1070#x1075-#x1081#x108E#x1100-#x1248#x124A-#x124D#x1250-#x1256#x1258#x125A-#x125D#x1260-#x1288#x128A-#x128D#x1290-#x12B0#x12B2-#x12B5#x12B8-#x12BE#x12C0#x12C2-#x12C5#x12C8-#x12D6#x12D8-#x1310#x1312-#x1315#x1318-#x135A#x1380-#x138F#x1401-#x166C#x166F-#x167F#x1681-#x169A#x16A0-#x16EA#x16F1-#x16F8#x1700-#x1711#x171F-#x1731#x1740-#x1751#x1760-#x176C#x176E-#x1770#x1780-#x17B3#x17DC#x1820-#x1842#x1844-#x1878#x1880-#x1884#x1887-#x18A8#x18AA#x18B0-#x18F5#x1900-#x191E#x1950-#x196D#x1970-#x1974#x1980-#x19AB#x19B0-#x19C9#x1A00-#x1A16#x1A20-#x1A54#x1B05-#x1B33#x1B45-#x1B4C#x1B83-#x1BA0#x1BAE-#x1BAF#x1BBA-#x1BE5#x1C00-#x1C23#x1C4D-#x1C4F#x1C5A-#x1C77#x1CE9-#x1CEC#x1CEE-#x1CF3#x1CF5-#x1CF6#x1CFA#x2135-#x2138#x2D30-#x2D67#x2D80-#x2D96#x2DA0-#x2DA6#x2DA8-#x2DAE#x2DB0-#x2DB6#x2DB8-#x2DBE#x2DC0-#x2DC6#x2DC8-#x2DCE#x2DD0-#x2DD6#x2DD8-#x2DDE#x3006#x303C#x3041-#x3096#x309F#x30A1-#x30FA#x30FF#x3105-#x312F#x3131-#x318E#x31A0-#x31BF#x31F0-#x31FF#x4DBF#x9FFF-#xA014#xA016-#xA48C#xA4D0-#xA4F7#xA500-#xA60B#xA610-#xA61F#xA62A-#xA62B#xA66E#xA6A0-#xA6E5#xA78F#xA7F7#xA7FB-#xA801#xA803-#xA805#xA807-#xA80A#xA80C-#xA822#xA840-#xA873#xA882-#xA8B3#xA8F2-#xA8F7#xA8FB#xA8FD-#xA8FE#xA90A-#xA925#xA930-#xA946#xA960-#xA97C#xA984-#xA9B2#xA9E0-#xA9E4#xA9E7-#xA9EF#xA9FA-#xA9FE#xAA00-#xAA28#xAA40-#xAA42#xAA44-#xAA4B#xAA60-#xAA6F#xAA71-#xAA76#xAA7A#xAA7E-#xAAAF#xAAB1#xAAB5-#xAAB6#xAAB9-#xAABD#xAAC0#xAAC2#xAADB-#xAADC#xAAE0-#xAAEA#xAAF2#xAB01-#xAB06#xAB09-#xAB0E#xAB11-#xAB16#xAB20-#xAB26#xAB28-#xAB2E#xABC0-#xABE2#xD7A3#xD7B0-#xD7C6#xD7CB-#xD7FB#xF900-#xFA6D#xFA70-#xFAD9#xFB1D#xFB1F-#xFB28#xFB2A-#xFB36#xFB38-#xFB3C#xFB3E#xFB40-#xFB41#xFB43-#xFB44#xFB46-#xFBB1#xFBD3-#xFD3D#xFD50-#xFD8F#xFD92-#xFDC7#xFDF0-#xFDFB#xFE70-#xFE74#xFE76-#xFEFC#xFF66-#xFF6F#xFF71-#xFF9D#xFFA0-#xFFBE#xFFC2-#xFFC7#xFFCA-#xFFCF#xFFD2-#xFFD7#xFFDA-#xFFDC]
-
- Referenced by: -
- - -====================================================================================================================== -Lt -====================================================================================================================== - - -.. raw:: html - - - - - - [#x1C5] - - [#x1C8] - - [#x1CB] - - [#x1F2] - - [#x1F88-#x1F8F] - - [#x1F98-#x1F9F] - - [#x1FA8-#x1FAF] - - [#x1FBC] - - [#x1FCC] - - [#x1FFC] - - -
- -
Lt       ::= [#x1C5#x1C8#x1CB#x1F2#x1F88-#x1F8F#x1F98-#x1F9F#x1FA8-#x1FAF#x1FBC#x1FCC#x1FFC]
-
- Referenced by: -
- - -====================================================================================================================== -Lu -====================================================================================================================== - - -.. raw:: html - - - - - - [A-Z] - - [#xC0-#xD6] - - [#xD8-#xDE] - - [#x100] - - [#x102] - - [#x104] - - [#x106] - - [#x108] - - [#x10A] - - [#x10C] - - [#x10E] - - [#x110] - - [#x112] - - [#x114] - - [#x116] - - [#x118] - - [#x11A] - - [#x11C] - - [#x11E] - - [#x120] - - [#x122] - - [#x124] - - [#x126] - - [#x128] - - [#x12A] - - [#x12C] - - [#x12E] - - [#x130] - - [#x132] - - [#x134] - - [#x136] - - [#x139] - - [#x13B] - - [#x13D] - - [#x13F] - - [#x141] - - [#x143] - - [#x145] - - [#x147] - - [#x14A] - - [#x14C] - - [#x14E] - - [#x150] - - [#x152] - - [#x154] - - [#x156] - - [#x158] - - [#x15A] - - [#x15C] - - [#x15E] - - [#x160] - - [#x162] - - [#x164] - - [#x166] - - [#x168] - - [#x16A] - - [#x16C] - - [#x16E] - - [#x170] - - [#x172] - - [#x174] - - [#x176] - - [#x178-#x179] - - [#x17B] - - [#x17D] - - [#x181-#x182] - - [#x184] - - [#x186-#x187] - - [#x189-#x18B] - - [#x18E-#x191] - - [#x193-#x194] - - [#x196-#x198] - - [#x19C-#x19D] - - [#x19F-#x1A0] - - [#x1A2] - - [#x1A4] - - [#x1A6-#x1A7] - - [#x1A9] - - [#x1AC] - - [#x1AE-#x1AF] - - [#x1B1-#x1B3] - - [#x1B5] - - [#x1B7-#x1B8] - - [#x1BC] - - [#x1C4] - - [#x1C7] - - [#x1CA] - - [#x1CD] - - [#x1CF] - - [#x1D1] - - [#x1D3] - - [#x1D5] - - [#x1D7] - - [#x1D9] - - [#x1DB] - - [#x1DE] - - [#x1E0] - - [#x1E2] - - [#x1E4] - - [#x1E6] - - [#x1E8] - - [#x1EA] - - [#x1EC] - - [#x1EE] - - [#x1F1] - - [#x1F4] - - [#x1F6-#x1F8] - - [#x1FA] - - [#x1FC] - - [#x1FE] - - [#x200] - - [#x202] - - [#x204] - - [#x206] - - [#x208] - - [#x20A] - - [#x20C] - - [#x20E] - - [#x210] - - [#x212] - - [#x214] - - [#x216] - - [#x218] - - [#x21A] - - [#x21C] - - [#x21E] - - [#x220] - - [#x222] - - [#x224] - - [#x226] - - [#x228] - - [#x22A] - - [#x22C] - - [#x22E] - - [#x230] - - [#x232] - - [#x23A-#x23B] - - [#x23D-#x23E] - - [#x241] - - [#x243-#x246] - - [#x248] - - [#x24A] - - [#x24C] - - [#x24E] - - [#x370] - - [#x372] - - [#x376] - - [#x37F] - - [#x386] - - [#x388-#x38A] - - [#x38C] - - [#x38E-#x38F] - - [#x391-#x3A1] - - [#x3A3-#x3AB] - - [#x3CF] - - [#x3D2-#x3D4] - - [#x3D8] - - [#x3DA] - - [#x3DC] - - [#x3DE] - - [#x3E0] - - [#x3E2] - - [#x3E4] - - [#x3E6] - - [#x3E8] - - [#x3EA] - - [#x3EC] - - [#x3EE] - - [#x3F4] - - [#x3F7] - - [#x3F9-#x3FA] - - [#x3FD-#x42F] - - [#x460] - - [#x462] - - [#x464] - - [#x466] - - [#x468] - - [#x46A] - - [#x46C] - - [#x46E] - - [#x470] - - [#x472] - - [#x474] - - [#x476] - - [#x478] - - [#x47A] - - [#x47C] - - [#x47E] - - [#x480] - - [#x48A] - - [#x48C] - - [#x48E] - - [#x490] - - [#x492] - - [#x494] - - [#x496] - - [#x498] - - [#x49A] - - [#x49C] - - [#x49E] - - [#x4A0] - - [#x4A2] - - [#x4A4] - - [#x4A6] - - [#x4A8] - - [#x4AA] - - [#x4AC] - - [#x4AE] - - [#x4B0] - - [#x4B2] - - [#x4B4] - - [#x4B6] - - [#x4B8] - - [#x4BA] - - [#x4BC] - - [#x4BE] - - [#x4C0-#x4C1] - - [#x4C3] - - [#x4C5] - - [#x4C7] - - [#x4C9] - - [#x4CB] - - [#x4CD] - - [#x4D0] - - [#x4D2] - - [#x4D4] - - [#x4D6] - - [#x4D8] - - [#x4DA] - - [#x4DC] - - [#x4DE] - - [#x4E0] - - [#x4E2] - - [#x4E4] - - [#x4E6] - - [#x4E8] - - [#x4EA] - - [#x4EC] - - [#x4EE] - - [#x4F0] - - [#x4F2] - - [#x4F4] - - [#x4F6] - - [#x4F8] - - [#x4FA] - - [#x4FC] - - [#x4FE] - - [#x500] - - [#x502] - - [#x504] - - [#x506] - - [#x508] - - [#x50A] - - [#x50C] - - [#x50E] - - [#x510] - - [#x512] - - [#x514] - - [#x516] - - [#x518] - - [#x51A] - - [#x51C] - - [#x51E] - - [#x520] - - [#x522] - - [#x524] - - [#x526] - - [#x528] - - [#x52A] - - [#x52C] - - [#x52E] - - [#x531-#x556] - - [#x10A0-#x10C5] - - [#x10C7] - - [#x10CD] - - [#x13A0-#x13F5] - - [#x1C90-#x1CBA] - - [#x1CBD-#x1CBF] - - [#x1E00] - - [#x1E02] - - [#x1E04] - - [#x1E06] - - [#x1E08] - - [#x1E0A] - - [#x1E0C] - - [#x1E0E] - - [#x1E10] - - [#x1E12] - - [#x1E14] - - [#x1E16] - - [#x1E18] - - [#x1E1A] - - [#x1E1C] - - [#x1E1E] - - [#x1E20] - - [#x1E22] - - [#x1E24] - - [#x1E26] - - [#x1E28] - - [#x1E2A] - - [#x1E2C] - - [#x1E2E] - - [#x1E30] - - [#x1E32] - - [#x1E34] - - [#x1E36] - - [#x1E38] - - [#x1E3A] - - [#x1E3C] - - [#x1E3E] - - [#x1E40] - - [#x1E42] - - [#x1E44] - - [#x1E46] - - [#x1E48] - - [#x1E4A] - - [#x1E4C] - - [#x1E4E] - - [#x1E50] - - [#x1E52] - - [#x1E54] - - [#x1E56] - - [#x1E58] - - [#x1E5A] - - [#x1E5C] - - [#x1E5E] - - [#x1E60] - - [#x1E62] - - [#x1E64] - - [#x1E66] - - [#x1E68] - - [#x1E6A] - - [#x1E6C] - - [#x1E6E] - - [#x1E70] - - [#x1E72] - - [#x1E74] - - [#x1E76] - - [#x1E78] - - [#x1E7A] - - [#x1E7C] - - [#x1E7E] - - [#x1E80] - - [#x1E82] - - [#x1E84] - - [#x1E86] - - [#x1E88] - - [#x1E8A] - - [#x1E8C] - - [#x1E8E] - - [#x1E90] - - [#x1E92] - - [#x1E94] - - [#x1E9E] - - [#x1EA0] - - [#x1EA2] - - [#x1EA4] - - [#x1EA6] - - [#x1EA8] - - [#x1EAA] - - [#x1EAC] - - [#x1EAE] - - [#x1EB0] - - [#x1EB2] - - [#x1EB4] - - [#x1EB6] - - [#x1EB8] - - [#x1EBA] - - [#x1EBC] - - [#x1EBE] - - [#x1EC0] - - [#x1EC2] - - [#x1EC4] - - [#x1EC6] - - [#x1EC8] - - [#x1ECA] - - [#x1ECC] - - [#x1ECE] - - [#x1ED0] - - [#x1ED2] - - [#x1ED4] - - [#x1ED6] - - [#x1ED8] - - [#x1EDA] - - [#x1EDC] - - [#x1EDE] - - [#x1EE0] - - [#x1EE2] - - [#x1EE4] - - [#x1EE6] - - [#x1EE8] - - [#x1EEA] - - [#x1EEC] - - [#x1EEE] - - [#x1EF0] - - [#x1EF2] - - [#x1EF4] - - [#x1EF6] - - [#x1EF8] - - [#x1EFA] - - [#x1EFC] - - [#x1EFE] - - [#x1F08-#x1F0F] - - [#x1F18-#x1F1D] - - [#x1F28-#x1F2F] - - [#x1F38-#x1F3F] - - [#x1F48-#x1F4D] - - [#x1F59] - - [#x1F5B] - - [#x1F5D] - - [#x1F5F] - - [#x1F68-#x1F6F] - - [#x1FB8-#x1FBB] - - [#x1FC8-#x1FCB] - - [#x1FD8-#x1FDB] - - [#x1FE8-#x1FEC] - - [#x1FF8-#x1FFB] - - [#x2102] - - [#x2107] - - [#x210B-#x210D] - - [#x2110-#x2112] - - [#x2115] - - [#x2119-#x211D] - - [#x2124] - - [#x2126] - - [#x2128] - - [#x212A-#x212D] - - [#x2130-#x2133] - - [#x213E-#x213F] - - [#x2145] - - [#x2183] - - [#x2C00-#x2C2F] - - [#x2C60] - - [#x2C62-#x2C64] - - [#x2C67] - - [#x2C69] - - [#x2C6B] - - [#x2C6D-#x2C70] - - [#x2C72] - - [#x2C75] - - [#x2C7E-#x2C80] - - [#x2C82] - - [#x2C84] - - [#x2C86] - - [#x2C88] - - [#x2C8A] - - [#x2C8C] - - [#x2C8E] - - [#x2C90] - - [#x2C92] - - [#x2C94] - - [#x2C96] - - [#x2C98] - - [#x2C9A] - - [#x2C9C] - - [#x2C9E] - - [#x2CA0] - - [#x2CA2] - - [#x2CA4] - - [#x2CA6] - - [#x2CA8] - - [#x2CAA] - - [#x2CAC] - - [#x2CAE] - - [#x2CB0] - - [#x2CB2] - - [#x2CB4] - - [#x2CB6] - - [#x2CB8] - - [#x2CBA] - - [#x2CBC] - - [#x2CBE] - - [#x2CC0] - - [#x2CC2] - - [#x2CC4] - - [#x2CC6] - - [#x2CC8] - - [#x2CCA] - - [#x2CCC] - - [#x2CCE] - - [#x2CD0] - - [#x2CD2] - - [#x2CD4] - - [#x2CD6] - - [#x2CD8] - - [#x2CDA] - - [#x2CDC] - - [#x2CDE] - - [#x2CE0] - - [#x2CE2] - - [#x2CEB] - - [#x2CED] - - [#x2CF2] - - [#xA640] - - [#xA642] - - [#xA644] - - [#xA646] - - [#xA648] - - [#xA64A] - - [#xA64C] - - [#xA64E] - - [#xA650] - - [#xA652] - - [#xA654] - - [#xA656] - - [#xA658] - - [#xA65A] - - [#xA65C] - - [#xA65E] - - [#xA660] - - [#xA662] - - [#xA664] - - [#xA666] - - [#xA668] - - [#xA66A] - - [#xA66C] - - [#xA680] - - [#xA682] - - [#xA684] - - [#xA686] - - [#xA688] - - [#xA68A] - - [#xA68C] - - [#xA68E] - - [#xA690] - - [#xA692] - - [#xA694] - - [#xA696] - - [#xA698] - - [#xA69A] - - [#xA722] - - [#xA724] - - [#xA726] - - [#xA728] - - [#xA72A] - - [#xA72C] - - [#xA72E] - - [#xA732] - - [#xA734] - - [#xA736] - - [#xA738] - - [#xA73A] - - [#xA73C] - - [#xA73E] - - [#xA740] - - [#xA742] - - [#xA744] - - [#xA746] - - [#xA748] - - [#xA74A] - - [#xA74C] - - [#xA74E] - - [#xA750] - - [#xA752] - - [#xA754] - - [#xA756] - - [#xA758] - - [#xA75A] - - [#xA75C] - - [#xA75E] - - [#xA760] - - [#xA762] - - [#xA764] - - [#xA766] - - [#xA768] - - [#xA76A] - - [#xA76C] - - [#xA76E] - - [#xA779] - - [#xA77B] - - [#xA77D-#xA77E] - - [#xA780] - - [#xA782] - - [#xA784] - - [#xA786] - - [#xA78B] - - [#xA78D] - - [#xA790] - - [#xA792] - - [#xA796] - - [#xA798] - - [#xA79A] - - [#xA79C] - - [#xA79E] - - [#xA7A0] - - [#xA7A2] - - [#xA7A4] - - [#xA7A6] - - [#xA7A8] - - [#xA7AA-#xA7AE] - - [#xA7B0-#xA7B4] - - [#xA7B6] - - [#xA7B8] - - [#xA7BA] - - [#xA7BC] - - [#xA7BE] - - [#xA7C0] - - [#xA7C2] - - [#xA7C4-#xA7C7] - - [#xA7C9] - - [#xA7D0] - - [#xA7D6] - - [#xA7D8] - - [#xA7F5] - - [#xFF21-#xFF3A] - - -
- -
Lu       ::= [A-Z#xC0-#xD6#xD8-#xDE#x100#x102#x104#x106#x108#x10A#x10C#x10E#x110#x112#x114#x116#x118#x11A#x11C#x11E#x120#x122#x124#x126#x128#x12A#x12C#x12E#x130#x132#x134#x136#x139#x13B#x13D#x13F#x141#x143#x145#x147#x14A#x14C#x14E#x150#x152#x154#x156#x158#x15A#x15C#x15E#x160#x162#x164#x166#x168#x16A#x16C#x16E#x170#x172#x174#x176#x178-#x179#x17B#x17D#x181-#x182#x184#x186-#x187#x189-#x18B#x18E-#x191#x193-#x194#x196-#x198#x19C-#x19D#x19F-#x1A0#x1A2#x1A4#x1A6-#x1A7#x1A9#x1AC#x1AE-#x1AF#x1B1-#x1B3#x1B5#x1B7-#x1B8#x1BC#x1C4#x1C7#x1CA#x1CD#x1CF#x1D1#x1D3#x1D5#x1D7#x1D9#x1DB#x1DE#x1E0#x1E2#x1E4#x1E6#x1E8#x1EA#x1EC#x1EE#x1F1#x1F4#x1F6-#x1F8#x1FA#x1FC#x1FE#x200#x202#x204#x206#x208#x20A#x20C#x20E#x210#x212#x214#x216#x218#x21A#x21C#x21E#x220#x222#x224#x226#x228#x22A#x22C#x22E#x230#x232#x23A-#x23B#x23D-#x23E#x241#x243-#x246#x248#x24A#x24C#x24E#x370#x372#x376#x37F#x386#x388-#x38A#x38C#x38E-#x38F#x391-#x3A1#x3A3-#x3AB#x3CF#x3D2-#x3D4#x3D8#x3DA#x3DC#x3DE#x3E0#x3E2#x3E4#x3E6#x3E8#x3EA#x3EC#x3EE#x3F4#x3F7#x3F9-#x3FA#x3FD-#x42F#x460#x462#x464#x466#x468#x46A#x46C#x46E#x470#x472#x474#x476#x478#x47A#x47C#x47E#x480#x48A#x48C#x48E#x490#x492#x494#x496#x498#x49A#x49C#x49E#x4A0#x4A2#x4A4#x4A6#x4A8#x4AA#x4AC#x4AE#x4B0#x4B2#x4B4#x4B6#x4B8#x4BA#x4BC#x4BE#x4C0-#x4C1#x4C3#x4C5#x4C7#x4C9#x4CB#x4CD#x4D0#x4D2#x4D4#x4D6#x4D8#x4DA#x4DC#x4DE#x4E0#x4E2#x4E4#x4E6#x4E8#x4EA#x4EC#x4EE#x4F0#x4F2#x4F4#x4F6#x4F8#x4FA#x4FC#x4FE#x500#x502#x504#x506#x508#x50A#x50C#x50E#x510#x512#x514#x516#x518#x51A#x51C#x51E#x520#x522#x524#x526#x528#x52A#x52C#x52E#x531-#x556#x10A0-#x10C5#x10C7#x10CD#x13A0-#x13F5#x1C90-#x1CBA#x1CBD-#x1CBF#x1E00#x1E02#x1E04#x1E06#x1E08#x1E0A#x1E0C#x1E0E#x1E10#x1E12#x1E14#x1E16#x1E18#x1E1A#x1E1C#x1E1E#x1E20#x1E22#x1E24#x1E26#x1E28#x1E2A#x1E2C#x1E2E#x1E30#x1E32#x1E34#x1E36#x1E38#x1E3A#x1E3C#x1E3E#x1E40#x1E42#x1E44#x1E46#x1E48#x1E4A#x1E4C#x1E4E#x1E50#x1E52#x1E54#x1E56#x1E58#x1E5A#x1E5C#x1E5E#x1E60#x1E62#x1E64#x1E66#x1E68#x1E6A#x1E6C#x1E6E#x1E70#x1E72#x1E74#x1E76#x1E78#x1E7A#x1E7C#x1E7E#x1E80#x1E82#x1E84#x1E86#x1E88#x1E8A#x1E8C#x1E8E#x1E90#x1E92#x1E94#x1E9E#x1EA0#x1EA2#x1EA4#x1EA6#x1EA8#x1EAA#x1EAC#x1EAE#x1EB0#x1EB2#x1EB4#x1EB6#x1EB8#x1EBA#x1EBC#x1EBE#x1EC0#x1EC2#x1EC4#x1EC6#x1EC8#x1ECA#x1ECC#x1ECE#x1ED0#x1ED2#x1ED4#x1ED6#x1ED8#x1EDA#x1EDC#x1EDE#x1EE0#x1EE2#x1EE4#x1EE6#x1EE8#x1EEA#x1EEC#x1EEE#x1EF0#x1EF2#x1EF4#x1EF6#x1EF8#x1EFA#x1EFC#x1EFE#x1F08-#x1F0F#x1F18-#x1F1D#x1F28-#x1F2F#x1F38-#x1F3F#x1F48-#x1F4D#x1F59#x1F5B#x1F5D#x1F5F#x1F68-#x1F6F#x1FB8-#x1FBB#x1FC8-#x1FCB#x1FD8-#x1FDB#x1FE8-#x1FEC#x1FF8-#x1FFB#x2102#x2107#x210B-#x210D#x2110-#x2112#x2115#x2119-#x211D#x2124#x2126#x2128#x212A-#x212D#x2130-#x2133#x213E-#x213F#x2145#x2183#x2C00-#x2C2F#x2C60#x2C62-#x2C64#x2C67#x2C69#x2C6B#x2C6D-#x2C70#x2C72#x2C75#x2C7E-#x2C80#x2C82#x2C84#x2C86#x2C88#x2C8A#x2C8C#x2C8E#x2C90#x2C92#x2C94#x2C96#x2C98#x2C9A#x2C9C#x2C9E#x2CA0#x2CA2#x2CA4#x2CA6#x2CA8#x2CAA#x2CAC#x2CAE#x2CB0#x2CB2#x2CB4#x2CB6#x2CB8#x2CBA#x2CBC#x2CBE#x2CC0#x2CC2#x2CC4#x2CC6#x2CC8#x2CCA#x2CCC#x2CCE#x2CD0#x2CD2#x2CD4#x2CD6#x2CD8#x2CDA#x2CDC#x2CDE#x2CE0#x2CE2#x2CEB#x2CED#x2CF2#xA640#xA642#xA644#xA646#xA648#xA64A#xA64C#xA64E#xA650#xA652#xA654#xA656#xA658#xA65A#xA65C#xA65E#xA660#xA662#xA664#xA666#xA668#xA66A#xA66C#xA680#xA682#xA684#xA686#xA688#xA68A#xA68C#xA68E#xA690#xA692#xA694#xA696#xA698#xA69A#xA722#xA724#xA726#xA728#xA72A#xA72C#xA72E#xA732#xA734#xA736#xA738#xA73A#xA73C#xA73E#xA740#xA742#xA744#xA746#xA748#xA74A#xA74C#xA74E#xA750#xA752#xA754#xA756#xA758#xA75A#xA75C#xA75E#xA760#xA762#xA764#xA766#xA768#xA76A#xA76C#xA76E#xA779#xA77B#xA77D-#xA77E#xA780#xA782#xA784#xA786#xA78B#xA78D#xA790#xA792#xA796#xA798#xA79A#xA79C#xA79E#xA7A0#xA7A2#xA7A4#xA7A6#xA7A8#xA7AA-#xA7AE#xA7B0-#xA7B4#xA7B6#xA7B8#xA7BA#xA7BC#xA7BE#xA7C0#xA7C2#xA7C4-#xA7C7#xA7C9#xA7D0#xA7D6#xA7D8#xA7F5#xFF21-#xFF3A]
-
- Referenced by: -
- - -====================================================================================================================== -Nl -====================================================================================================================== - - -.. raw:: html - - - - - - [#x16EE-#x16F0] - - [#x2160-#x2182] - - [#x2185-#x2188] - - [#x3007] - - [#x3021-#x3029] - - [#x3038-#x303A] - - [#xA6E6-#xA6EF] - - -
- -
Nl       ::= [#x16EE-#x16F0#x2160-#x2182#x2185-#x2188#x3007#x3021-#x3029#x3038-#x303A#xA6E6-#xA6EF]
-
- Referenced by: -
- - -====================================================================================================================== -UnicodeIdentifierExtend -====================================================================================================================== - - -.. raw:: html - - - - - - Mn - - Mc - - Nd - - Pc - - Cf - - CJK - -
- - -
         ::= Mn
-
           | Mc
-
           | Nd
-
           | Pc
-
           | Cf
-
           | CJK
-
- Referenced by: -
- - -====================================================================================================================== -Cf -====================================================================================================================== - - -.. raw:: html - - - - - - [#xAD] - - [#x600-#x605] - - [#x61C] - - [#x6DD] - - [#x70F] - - [#x890-#x891] - - [#x8E2] - - [#x180E] - - [#x200B-#x200F] - - [#x202A-#x202E] - - [#x2060-#x2064] - - [#x2066-#x206F] - - [#xFEFF] - - [#xFFF9-#xFFFB] - - -
- -
Cf       ::= [#xAD#x600-#x605#x61C#x6DD#x70F#x890-#x891#x8E2#x180E#x200B-#x200F#x202A-#x202E#x2060-#x2064#x2066-#x206F#xFEFF#xFFF9-#xFFFB]
-
- Referenced by: -
- - -====================================================================================================================== -Mc -====================================================================================================================== - - -.. raw:: html - - - - - - [#x903] - - [#x93B] - - [#x93E-#x940] - - [#x949-#x94C] - - [#x94E-#x94F] - - [#x982-#x983] - - [#x9BE-#x9C0] - - [#x9C7-#x9C8] - - [#x9CB-#x9CC] - - [#x9D7] - - [#xA03] - - [#xA3E-#xA40] - - [#xA83] - - [#xABE-#xAC0] - - [#xAC9] - - [#xACB-#xACC] - - [#xB02-#xB03] - - [#xB3E] - - [#xB40] - - [#xB47-#xB48] - - [#xB4B-#xB4C] - - [#xB57] - - [#xBBE-#xBBF] - - [#xBC1-#xBC2] - - [#xBC6-#xBC8] - - [#xBCA-#xBCC] - - [#xBD7] - - [#xC01-#xC03] - - [#xC41-#xC44] - - [#xC82-#xC83] - - [#xCBE] - - [#xCC0-#xCC4] - - [#xCC7-#xCC8] - - [#xCCA-#xCCB] - - [#xCD5-#xCD6] - - [#xCF3] - - [#xD02-#xD03] - - [#xD3E-#xD40] - - [#xD46-#xD48] - - [#xD4A-#xD4C] - - [#xD57] - - [#xD82-#xD83] - - [#xDCF-#xDD1] - - [#xDD8-#xDDF] - - [#xDF2-#xDF3] - - [#xF3E-#xF3F] - - [#xF7F] - - [#x102B-#x102C] - - [#x1031] - - [#x1038] - - [#x103B-#x103C] - - [#x1056-#x1057] - - [#x1062-#x1064] - - [#x1067-#x106D] - - [#x1083-#x1084] - - [#x1087-#x108C] - - [#x108F] - - [#x109A-#x109C] - - [#x1715] - - [#x1734] - - [#x17B6] - - [#x17BE-#x17C5] - - [#x17C7-#x17C8] - - [#x1923-#x1926] - - [#x1929-#x192B] - - [#x1930-#x1931] - - [#x1933-#x1938] - - [#x1A19-#x1A1A] - - [#x1A55] - - [#x1A57] - - [#x1A61] - - [#x1A63-#x1A64] - - [#x1A6D-#x1A72] - - [#x1B04] - - [#x1B35] - - [#x1B3B] - - [#x1B3D-#x1B41] - - [#x1B43-#x1B44] - - [#x1B82] - - [#x1BA1] - - [#x1BA6-#x1BA7] - - [#x1BAA] - - [#x1BE7] - - [#x1BEA-#x1BEC] - - [#x1BEE] - - [#x1BF2-#x1BF3] - - [#x1C24-#x1C2B] - - [#x1C34-#x1C35] - - [#x1CE1] - - [#x1CF7] - - [#x302E-#x302F] - - [#xA823-#xA824] - - [#xA827] - - [#xA880-#xA881] - - [#xA8B4-#xA8C3] - - [#xA952-#xA953] - - [#xA983] - - [#xA9B4-#xA9B5] - - [#xA9BA-#xA9BB] - - [#xA9BE-#xA9C0] - - [#xAA2F-#xAA30] - - [#xAA33-#xAA34] - - [#xAA4D] - - [#xAA7B] - - [#xAA7D] - - [#xAAEB] - - [#xAAEE-#xAAEF] - - [#xAAF5] - - [#xABE3-#xABE4] - - [#xABE6-#xABE7] - - [#xABE9-#xABEA] - - [#xABEC] - - -
- -
Mc       ::= [#x903#x93B#x93E-#x940#x949-#x94C#x94E-#x94F#x982-#x983#x9BE-#x9C0#x9C7-#x9C8#x9CB-#x9CC#x9D7#xA03#xA3E-#xA40#xA83#xABE-#xAC0#xAC9#xACB-#xACC#xB02-#xB03#xB3E#xB40#xB47-#xB48#xB4B-#xB4C#xB57#xBBE-#xBBF#xBC1-#xBC2#xBC6-#xBC8#xBCA-#xBCC#xBD7#xC01-#xC03#xC41-#xC44#xC82-#xC83#xCBE#xCC0-#xCC4#xCC7-#xCC8#xCCA-#xCCB#xCD5-#xCD6#xCF3#xD02-#xD03#xD3E-#xD40#xD46-#xD48#xD4A-#xD4C#xD57#xD82-#xD83#xDCF-#xDD1#xDD8-#xDDF#xDF2-#xDF3#xF3E-#xF3F#xF7F#x102B-#x102C#x1031#x1038#x103B-#x103C#x1056-#x1057#x1062-#x1064#x1067-#x106D#x1083-#x1084#x1087-#x108C#x108F#x109A-#x109C#x1715#x1734#x17B6#x17BE-#x17C5#x17C7-#x17C8#x1923-#x1926#x1929-#x192B#x1930-#x1931#x1933-#x1938#x1A19-#x1A1A#x1A55#x1A57#x1A61#x1A63-#x1A64#x1A6D-#x1A72#x1B04#x1B35#x1B3B#x1B3D-#x1B41#x1B43-#x1B44#x1B82#x1BA1#x1BA6-#x1BA7#x1BAA#x1BE7#x1BEA-#x1BEC#x1BEE#x1BF2-#x1BF3#x1C24-#x1C2B#x1C34-#x1C35#x1CE1#x1CF7#x302E-#x302F#xA823-#xA824#xA827#xA880-#xA881#xA8B4-#xA8C3#xA952-#xA953#xA983#xA9B4-#xA9B5#xA9BA-#xA9BB#xA9BE-#xA9C0#xAA2F-#xAA30#xAA33-#xAA34#xAA4D#xAA7B#xAA7D#xAAEB#xAAEE-#xAAEF#xAAF5#xABE3-#xABE4#xABE6-#xABE7#xABE9-#xABEA#xABEC]
-
- Referenced by: -
- - -====================================================================================================================== -Mn -====================================================================================================================== - - -.. raw:: html - - - - - - [#x300-#x36F] - - [#x483-#x487] - - [#x591-#x5BD] - - [#x5BF] - - [#x5C1-#x5C2] - - [#x5C4-#x5C5] - - [#x5C7] - - [#x610-#x61A] - - [#x64B-#x65F] - - [#x670] - - [#x6D6-#x6DC] - - [#x6DF-#x6E4] - - [#x6E7-#x6E8] - - [#x6EA-#x6ED] - - [#x711] - - [#x730-#x74A] - - [#x7A6-#x7B0] - - [#x7EB-#x7F3] - - [#x7FD] - - [#x816-#x819] - - [#x81B-#x823] - - [#x825-#x827] - - [#x829-#x82D] - - [#x859-#x85B] - - [#x898-#x89F] - - [#x8CA-#x8E1] - - [#x8E3-#x902] - - [#x93A] - - [#x93C] - - [#x941-#x948] - - [#x94D] - - [#x951-#x957] - - [#x962-#x963] - - [#x981] - - [#x9BC] - - [#x9C1-#x9C4] - - [#x9CD] - - [#x9E2-#x9E3] - - [#x9FE] - - [#xA01-#xA02] - - [#xA3C] - - [#xA41-#xA42] - - [#xA47-#xA48] - - [#xA4B-#xA4D] - - [#xA51] - - [#xA70-#xA71] - - [#xA75] - - [#xA81-#xA82] - - [#xABC] - - [#xAC1-#xAC5] - - [#xAC7-#xAC8] - - [#xACD] - - [#xAE2-#xAE3] - - [#xAFA-#xAFF] - - [#xB01] - - [#xB3C] - - [#xB3F] - - [#xB41-#xB44] - - [#xB4D] - - [#xB55-#xB56] - - [#xB62-#xB63] - - [#xB82] - - [#xBC0] - - [#xBCD] - - [#xC00] - - [#xC04] - - [#xC3C] - - [#xC3E-#xC40] - - [#xC46-#xC48] - - [#xC4A-#xC4D] - - [#xC55-#xC56] - - [#xC62-#xC63] - - [#xC81] - - [#xCBC] - - [#xCBF] - - [#xCC6] - - [#xCCC-#xCCD] - - [#xCE2-#xCE3] - - [#xD00-#xD01] - - [#xD3B-#xD3C] - - [#xD41-#xD44] - - [#xD4D] - - [#xD62-#xD63] - - [#xD81] - - [#xDCA] - - [#xDD2-#xDD4] - - [#xDD6] - - [#xE31] - - [#xE34-#xE3A] - - [#xE47-#xE4E] - - [#xEB1] - - [#xEB4-#xEBC] - - [#xEC8-#xECE] - - [#xF18-#xF19] - - [#xF35] - - [#xF37] - - [#xF39] - - [#xF71-#xF7E] - - [#xF80-#xF84] - - [#xF86-#xF87] - - [#xF8D-#xF97] - - [#xF99-#xFBC] - - [#xFC6] - - [#x102D-#x1030] - - [#x1032-#x1037] - - [#x1039-#x103A] - - [#x103D-#x103E] - - [#x1058-#x1059] - - [#x105E-#x1060] - - [#x1071-#x1074] - - [#x1082] - - [#x1085-#x1086] - - [#x108D] - - [#x109D] - - [#x135D-#x135F] - - [#x1712-#x1714] - - [#x1732-#x1733] - - [#x1752-#x1753] - - [#x1772-#x1773] - - [#x17B4-#x17B5] - - [#x17B7-#x17BD] - - [#x17C6] - - [#x17C9-#x17D3] - - [#x17DD] - - [#x180B-#x180D] - - [#x180F] - - [#x1885-#x1886] - - [#x18A9] - - [#x1920-#x1922] - - [#x1927-#x1928] - - [#x1932] - - [#x1939-#x193B] - - [#x1A17-#x1A18] - - [#x1A1B] - - [#x1A56] - - [#x1A58-#x1A5E] - - [#x1A60] - - [#x1A62] - - [#x1A65-#x1A6C] - - [#x1A73-#x1A7C] - - [#x1A7F] - - [#x1AB0-#x1ABD] - - [#x1ABF-#x1ACE] - - [#x1B00-#x1B03] - - [#x1B34] - - [#x1B36-#x1B3A] - - [#x1B3C] - - [#x1B42] - - [#x1B6B-#x1B73] - - [#x1B80-#x1B81] - - [#x1BA2-#x1BA5] - - [#x1BA8-#x1BA9] - - [#x1BAB-#x1BAD] - - [#x1BE6] - - [#x1BE8-#x1BE9] - - [#x1BED] - - [#x1BEF-#x1BF1] - - [#x1C2C-#x1C33] - - [#x1C36-#x1C37] - - [#x1CD0-#x1CD2] - - [#x1CD4-#x1CE0] - - [#x1CE2-#x1CE8] - - [#x1CED] - - [#x1CF4] - - [#x1CF8-#x1CF9] - - [#x1DC0-#x1DFF] - - [#x20D0-#x20DC] - - [#x20E1] - - [#x20E5-#x20F0] - - [#x2CEF-#x2CF1] - - [#x2D7F] - - [#x2DE0-#x2DFF] - - [#x302A-#x302D] - - [#x3099-#x309A] - - [#xA66F] - - [#xA674-#xA67D] - - [#xA69E-#xA69F] - - [#xA6F0-#xA6F1] - - [#xA802] - - [#xA806] - - [#xA80B] - - [#xA825-#xA826] - - [#xA82C] - - [#xA8C4-#xA8C5] - - [#xA8E0-#xA8F1] - - [#xA8FF] - - [#xA926-#xA92D] - - [#xA947-#xA951] - - [#xA980-#xA982] - - [#xA9B3] - - [#xA9B6-#xA9B9] - - [#xA9BC-#xA9BD] - - [#xA9E5] - - [#xAA29-#xAA2E] - - [#xAA31-#xAA32] - - [#xAA35-#xAA36] - - [#xAA43] - - [#xAA4C] - - [#xAA7C] - - [#xAAB0] - - [#xAAB2-#xAAB4] - - [#xAAB7-#xAAB8] - - [#xAABE-#xAABF] - - [#xAAC1] - - [#xAAEC-#xAAED] - - [#xAAF6] - - [#xABE5] - - [#xABE8] - - [#xABED] - - [#xFB1E] - - [#xFE00-#xFE0F] - - [#xFE20-#xFE2F] - - -
- -
Mn       ::= [#x300-#x36F#x483-#x487#x591-#x5BD#x5BF#x5C1-#x5C2#x5C4-#x5C5#x5C7#x610-#x61A#x64B-#x65F#x670#x6D6-#x6DC#x6DF-#x6E4#x6E7-#x6E8#x6EA-#x6ED#x711#x730-#x74A#x7A6-#x7B0#x7EB-#x7F3#x7FD#x816-#x819#x81B-#x823#x825-#x827#x829-#x82D#x859-#x85B#x898-#x89F#x8CA-#x8E1#x8E3-#x902#x93A#x93C#x941-#x948#x94D#x951-#x957#x962-#x963#x981#x9BC#x9C1-#x9C4#x9CD#x9E2-#x9E3#x9FE#xA01-#xA02#xA3C#xA41-#xA42#xA47-#xA48#xA4B-#xA4D#xA51#xA70-#xA71#xA75#xA81-#xA82#xABC#xAC1-#xAC5#xAC7-#xAC8#xACD#xAE2-#xAE3#xAFA-#xAFF#xB01#xB3C#xB3F#xB41-#xB44#xB4D#xB55-#xB56#xB62-#xB63#xB82#xBC0#xBCD#xC00#xC04#xC3C#xC3E-#xC40#xC46-#xC48#xC4A-#xC4D#xC55-#xC56#xC62-#xC63#xC81#xCBC#xCBF#xCC6#xCCC-#xCCD#xCE2-#xCE3#xD00-#xD01#xD3B-#xD3C#xD41-#xD44#xD4D#xD62-#xD63#xD81#xDCA#xDD2-#xDD4#xDD6#xE31#xE34-#xE3A#xE47-#xE4E#xEB1#xEB4-#xEBC#xEC8-#xECE#xF18-#xF19#xF35#xF37#xF39#xF71-#xF7E#xF80-#xF84#xF86-#xF87#xF8D-#xF97#xF99-#xFBC#xFC6#x102D-#x1030#x1032-#x1037#x1039-#x103A#x103D-#x103E#x1058-#x1059#x105E-#x1060#x1071-#x1074#x1082#x1085-#x1086#x108D#x109D#x135D-#x135F#x1712-#x1714#x1732-#x1733#x1752-#x1753#x1772-#x1773#x17B4-#x17B5#x17B7-#x17BD#x17C6#x17C9-#x17D3#x17DD#x180B-#x180D#x180F#x1885-#x1886#x18A9#x1920-#x1922#x1927-#x1928#x1932#x1939-#x193B#x1A17-#x1A18#x1A1B#x1A56#x1A58-#x1A5E#x1A60#x1A62#x1A65-#x1A6C#x1A73-#x1A7C#x1A7F#x1AB0-#x1ABD#x1ABF-#x1ACE#x1B00-#x1B03#x1B34#x1B36-#x1B3A#x1B3C#x1B42#x1B6B-#x1B73#x1B80-#x1B81#x1BA2-#x1BA5#x1BA8-#x1BA9#x1BAB-#x1BAD#x1BE6#x1BE8-#x1BE9#x1BED#x1BEF-#x1BF1#x1C2C-#x1C33#x1C36-#x1C37#x1CD0-#x1CD2#x1CD4-#x1CE0#x1CE2-#x1CE8#x1CED#x1CF4#x1CF8-#x1CF9#x1DC0-#x1DFF#x20D0-#x20DC#x20E1#x20E5-#x20F0#x2CEF-#x2CF1#x2D7F#x2DE0-#x2DFF#x302A-#x302D#x3099-#x309A#xA66F#xA674-#xA67D#xA69E-#xA69F#xA6F0-#xA6F1#xA802#xA806#xA80B#xA825-#xA826#xA82C#xA8C4-#xA8C5#xA8E0-#xA8F1#xA8FF#xA926-#xA92D#xA947-#xA951#xA980-#xA982#xA9B3#xA9B6-#xA9B9#xA9BC-#xA9BD#xA9E5#xAA29-#xAA2E#xAA31-#xAA32#xAA35-#xAA36#xAA43#xAA4C#xAA7C#xAAB0#xAAB2-#xAAB4#xAAB7-#xAAB8#xAABE-#xAABF#xAAC1#xAAEC-#xAAED#xAAF6#xABE5#xABE8#xABED#xFB1E#xFE00-#xFE0F#xFE20-#xFE2F]
-
- Referenced by: -
- - -====================================================================================================================== -Nd -====================================================================================================================== - - -.. raw:: html - - - - - - [0-9] - - [#x660-#x669] - - [#x6F0-#x6F9] - - [#x7C0-#x7C9] - - [#x966-#x96F] - - [#x9E6-#x9EF] - - [#xA66-#xA6F] - - [#xAE6-#xAEF] - - [#xB66-#xB6F] - - [#xBE6-#xBEF] - - [#xC66-#xC6F] - - [#xCE6-#xCEF] - - [#xD66-#xD6F] - - [#xDE6-#xDEF] - - [#xE50-#xE59] - - [#xED0-#xED9] - - [#xF20-#xF29] - - [#x1040-#x1049] - - [#x1090-#x1099] - - [#x17E0-#x17E9] - - [#x1810-#x1819] - - [#x1946-#x194F] - - [#x19D0-#x19D9] - - [#x1A80-#x1A89] - - [#x1A90-#x1A99] - - [#x1B50-#x1B59] - - [#x1BB0-#x1BB9] - - [#x1C40-#x1C49] - - [#x1C50-#x1C59] - - [#xA620-#xA629] - - [#xA8D0-#xA8D9] - - [#xA900-#xA909] - - [#xA9D0-#xA9D9] - - [#xA9F0-#xA9F9] - - [#xAA50-#xAA59] - - [#xABF0-#xABF9] - - [#xFF10-#xFF19] - - -
- -
Nd       ::= [0-9#x660-#x669#x6F0-#x6F9#x7C0-#x7C9#x966-#x96F#x9E6-#x9EF#xA66-#xA6F#xAE6-#xAEF#xB66-#xB6F#xBE6-#xBEF#xC66-#xC6F#xCE6-#xCEF#xD66-#xD6F#xDE6-#xDEF#xE50-#xE59#xED0-#xED9#xF20-#xF29#x1040-#x1049#x1090-#x1099#x17E0-#x17E9#x1810-#x1819#x1946-#x194F#x19D0-#x19D9#x1A80-#x1A89#x1A90-#x1A99#x1B50-#x1B59#x1BB0-#x1BB9#x1C40-#x1C49#x1C50-#x1C59#xA620-#xA629#xA8D0-#xA8D9#xA900-#xA909#xA9D0-#xA9D9#xA9F0-#xA9F9#xAA50-#xAA59#xABF0-#xABF9#xFF10-#xFF19]
-
- Referenced by: -
- - -====================================================================================================================== -Pc -====================================================================================================================== - - -.. raw:: html - - - - - - [#x203F-#x2040] - - [#x2054] - - [#xFE33-#xFE34] - - [#xFE4D-#xFE4F] - - [#xFF3F] - - -
- -
Pc       ::= [#x203F-#x2040#x2054#xFE33-#xFE34#xFE4D-#xFE4F#xFF3F]
-
- Referenced by: -
- - -====================================================================================================================== -CJK -====================================================================================================================== - - -.. raw:: html - - - - - - [#xAC00-#xD7A3] - - [#x4E00-#x9FFF] - - -
- -
CJK      ::= [#xAC00-#xD7A3#x4E00-#x9FFF]
-
- - -====================================================================================================================== -ESC -====================================================================================================================== - - -.. raw:: html - - - - - - \ - - n - - t - - b - - r - - f - - \ - - " - - -
- -
ESC      ::= '\' [ntbrf\"]
-
- Referenced by: -
- - -====================================================================================================================== -S_CHAR_LITERAL -====================================================================================================================== - - -.. raw:: html - - - - - - U - - E - - N - - R - - B - - RB - - _utf8 - - q'{ - - . - - }' - - ' - - ESC - \' - - [^'\] - - '' - - [^'] - - ' - - q'( - - . - - )' - - q'[ - - . - - ]' - - q'' - - . - - '' - - -
- - -
         ::= ( [UENRB] | 'RB' | '_utf8' )? ( "'" ( ( ESC | "\'" | [^'\] )* | ( "''" | [^'] )+ ) "'" | "q'{" .* "}'" | "q'(" .* ")'" | "q'[" .* "]'" | "q''" .* "''" )
-
- - -====================================================================================================================== -S_QUOTED_IDENTIFIER -====================================================================================================================== - - -.. raw:: html - - - - - - " - - "" - - [^"#xA#xD] - - " - - $$ - - [^$] - - $$ - - ` - - [^`#xA#xD] - - ` - - [ - - [^#x5D#xA#xD] - - ] - - -
- - -
         ::= '"' ( '""' | [^"#xA#xD] )* '"'
-
           | '$$' [^$]* '$$'
-
           | '`' [^`#xA#xD]+ '`'
-
           | '[' [^#x5D#xA#xD]* ']'
-
- - -====================================================================================================================== -EOF -====================================================================================================================== - - -.. raw:: html - - - - - - $ - - -
- -
EOF      ::= $
-
- Referenced by: -
- - \ No newline at end of file diff --git a/src/site/sphinx/unsupported.rst b/src/site/sphinx/unsupported.rst new file mode 100644 index 000000000..b6489a84a --- /dev/null +++ b/src/site/sphinx/unsupported.rst @@ -0,0 +1,57 @@ +*************************************** +Unsupported Grammar of various RDBMS +*************************************** + +*JSQLParser* is a RDBMS agnostic parser with a certain focus on SQL:2016 Standard compliant Queries and the "Big Four" (Oracle, MS SQL Server, Postgres, MySQL/MariaDB). +We would like to recommend writing portable, standard compliant SQL in general. + +- Postgres Implicit cast is not supported. + + .. code-block:: java + + SELECT date '2022-12-31'; + SELECT double precision 1; + + +- Oracle PL/SQL blocks are not support. + + .. code-block:: sql + + DECLARE + num NUMBER; + BEGIN + num := 10; + dbms_output.put_line('The number is ' || num); + END; + + + +- Oracle `INSERT ALL ...` is not supported + + .. code-block:: sql + + INSERT ALL + INTO mytable (column1, column2, column_n) VALUES (expr1, expr2, expr_n) + INTO mytable (column1, column2, column_n) VALUES (expr1, expr2, expr_n) + INTO mytable (column1, column2, column_n) VALUES (expr1, expr2, expr_n) + SELECT * FROM dual; + +- DDL statements + + While *JSQLParser* provides a lot of generic support for DDL statements, it is possible that certain RDBMS specific syntax (especially about indices, encodings, compression) won't be supported. + +- `JSON` or `XML` specific syntax and functions + + While *JSQLParser* provides a lot of generic support for `JSON` or `XML` processing, it is possible that certain RDBMS specific syntax or functions won't be supported. + +- Interval Operators + + Anything like `DAY HOUR MINUTE SECOND [TO HOUR MINUTE SECOND]` is not supported.: + + .. code-block:: sql + + values cast ((time '12:03:34' - time '11:57:23') minute to second as varchar(8)); + + + + diff --git a/src/test/java/net/sf/jsqlparser/expression/CaseExpressionTest.java b/src/test/java/net/sf/jsqlparser/expression/CaseExpressionTest.java index 0e7d3a6d8..e86f92a2b 100644 --- a/src/test/java/net/sf/jsqlparser/expression/CaseExpressionTest.java +++ b/src/test/java/net/sf/jsqlparser/expression/CaseExpressionTest.java @@ -19,67 +19,80 @@ public class CaseExpressionTest { @Test public void testSimpleCase() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true WHEN true THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true WHEN true THEN 1 ELSE 2 END", + true); } @Test public void testCaseBinaryAndWhen() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true WHEN true & false THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed( + "CASE true WHEN true & false THEN 1 ELSE 2 END", true); } @Test public void testCaseBinaryOrWhen() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true WHEN true | false THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed( + "CASE true WHEN true | false THEN 1 ELSE 2 END", true); } @Test public void testCaseExclamationWhen() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true WHEN !true THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true WHEN !true THEN 1 ELSE 2 END", + true); } @Test public void testCaseNotWhen() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true WHEN NOT true THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed( + "CASE true WHEN NOT true THEN 1 ELSE 2 END", true); } @Test public void testCaseAndWhen() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true WHEN true AND false THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed( + "CASE true WHEN true AND false THEN 1 ELSE 2 END", true); } @Test public void testCaseOrWhen() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true WHEN true OR false THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed( + "CASE true WHEN true OR false THEN 1 ELSE 2 END", true); } @Test public void testCaseExclamationSwitch() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE !true WHEN true THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE !true WHEN true THEN 1 ELSE 2 END", + true); } @Test public void testCaseNotSwitch() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE NOT true WHEN true THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed( + "CASE NOT true WHEN true THEN 1 ELSE 2 END", true); } @Test public void testCaseBinaryAndSwitch() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true & false WHEN true THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed( + "CASE true & false WHEN true THEN 1 ELSE 2 END", true); } @Test public void testCaseBinaryOrSwitch() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true | false WHEN true THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed( + "CASE true | false WHEN true THEN 1 ELSE 2 END", true); } @Test public void testCaseAndSwitch() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true AND false WHEN true THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed( + "CASE true AND false WHEN true THEN 1 ELSE 2 END", true); } @Test public void testCaseOrSwitch() throws JSQLParserException { - TestUtils.assertExpressionCanBeParsedAndDeparsed("CASE true OR false WHEN true THEN 1 ELSE 2 END", true); + TestUtils.assertExpressionCanBeParsedAndDeparsed( + "CASE true OR false WHEN true THEN 1 ELSE 2 END", true); } @Test @@ -112,24 +125,38 @@ public void testInnerCaseWithConcatInElsePart() throws JSQLParserException { @Test public void testCaseInsideBrackets() throws JSQLParserException { String sqlStr = "SELECT ( CASE\n" - + " WHEN something\n" - + " THEN CASE\n" - + " WHEN something2\n" - + " THEN 1\n" - + " ELSE 0\n" - + " END + 1\n" - + " ELSE 0\n" - + " END ) + 1 \n" - + "FROM test"; + + " WHEN something\n" + + " THEN CASE\n" + + " WHEN something2\n" + + " THEN 1\n" + + " ELSE 0\n" + + " END + 1\n" + + " ELSE 0\n" + + " END ) + 1 \n" + + "FROM test"; TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); sqlStr = "SELECT\n" - + "(CASE WHEN FIELD_A=0 THEN FIELD_B\n" - + "WHEN FIELD_C >FIELD_D THEN (CASE WHEN FIELD_A>0 THEN\n" - + "(FIELD_B)/(FIELD_A/(DATEDIFF(DAY,:started,:end)+1))\n" - + "ELSE 0 END)-FIELD_D ELSE 0 END)*FIELD_A/(DATEDIFF(DAY,:started,:end)+1) AS UNNECESSARY_COMPLEX_EXPRESSION\n" - + "FROM TEST"; + + "(CASE WHEN FIELD_A=0 THEN FIELD_B\n" + + "WHEN FIELD_C >FIELD_D THEN (CASE WHEN FIELD_A>0 THEN\n" + + "(FIELD_B)/(FIELD_A/(DATEDIFF(DAY,:started,:end)+1))\n" + + "ELSE 0 END)-FIELD_D ELSE 0 END)*FIELD_A/(DATEDIFF(DAY,:started,:end)+1) AS UNNECESSARY_COMPLEX_EXPRESSION\n" + + "FROM TEST"; + + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } + + @Test + void testPerformanceIssue1889() throws JSQLParserException { + String sqlStr = "SELECT " + + "SUM(SUM(CASE\n" + + " WHEN IssueDeadline IS NULL THEN 'Indeterminate'\n" + + " WHEN IssueDeadline < CONVERT(DATETIME, CONVERT(DATE, COALESCE(IssueClosedOn, CONVERT(DATETIME, CONVERT(DATE, GETDATE()), 121)))) THEN 'PastDue'\n" + + " WHEN (IssueDeadline>=CONVERT(DATETIME, CONVERT(DATE, GETDATE()), 121)\n" + + " AND IssueDeadline<=CONVERT(DATETIME, CONVERT(DATE, GETDATE()+3), 121)) THEN 'Alert'\n" + + " ELSE 'OnTime'\n" + + " END = 'PastDue'))\n"; TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); } diff --git a/src/test/java/net/sf/jsqlparser/expression/OracleHintTest.java b/src/test/java/net/sf/jsqlparser/expression/OracleHintTest.java new file mode 100644 index 000000000..2da69721c --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/expression/OracleHintTest.java @@ -0,0 +1,49 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2023 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.expression; + +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.test.TestUtils; +import org.junit.jupiter.api.Test; + +class OracleHintTest { + + @Test + void testSelect() throws JSQLParserException { + String sqlString = "SELECT /*+parallel*/ * from dual"; + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlString, true); + } + + @Test + void testDelete() throws JSQLParserException { + String sqlString = "DELETE /*+parallel*/ from dual"; + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlString, true); + } + + @Test + void testInsert() throws JSQLParserException { + String sqlString = "INSERT /*+parallel*/ INTO dual VALUES(1)"; + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlString, true); + } + + @Test + void testUpdate() throws JSQLParserException { + String sqlString = "UPDATE /*+parallel*/ dual SET a=b"; + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlString, true); + } + + @Test + void testMerge() throws JSQLParserException { + String sqlString = + "MERGE /*+parallel*/ INTO dual USING z ON (a=b) WHEN MATCHED THEN UPDATE SET a=b"; + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlString, true); + } + +} diff --git a/src/test/java/net/sf/jsqlparser/expression/operators/relational/ComparisonOperatorTest.java b/src/test/java/net/sf/jsqlparser/expression/operators/relational/ComparisonOperatorTest.java new file mode 100644 index 000000000..a2687d664 --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/expression/operators/relational/ComparisonOperatorTest.java @@ -0,0 +1,38 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2023 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.expression.operators.relational; + +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.test.TestUtils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + + +class ComparisonOperatorTest { + + @Test + public void testDoubleAnd() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM foo WHERE a && b"); + Assertions.assertInstanceOf(DoubleAnd.class, CCJSqlParserUtil.parseExpression("a && b")); + } + + @Test + public void testContains() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM foo WHERE a &> b"); + Assertions.assertInstanceOf(Contains.class, CCJSqlParserUtil.parseExpression("a &> b")); + } + + @Test + public void testContainedBy() throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT * FROM foo WHERE a <& b"); + Assertions.assertInstanceOf(ContainedBy.class, CCJSqlParserUtil.parseExpression("a <& b")); + } +} diff --git a/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java b/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java index 0b78f60d0..1ec07b531 100644 --- a/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java +++ b/src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java @@ -9,6 +9,12 @@ */ package net.sf.jsqlparser.parser; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.io.ByteArrayInputStream; import java.io.StringReader; import java.nio.charset.StandardCharsets; @@ -19,7 +25,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.logging.Level; - import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.LongValue; @@ -29,15 +34,9 @@ import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.Statements; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - import net.sf.jsqlparser.statement.UnsupportedStatement; import net.sf.jsqlparser.statement.select.PlainSelect; +import net.sf.jsqlparser.statement.select.TableStatement; import net.sf.jsqlparser.test.MemoryLeakVerifier; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; @@ -336,6 +335,13 @@ public void testCondExpressionIssue1482() throws JSQLParserException { assertEquals("test_table_enum.f1_enum IN ('TEST2'::test.test_enum)", expr.toString()); } + @Test + public void testTableStatementIssue1836() throws JSQLParserException { + TableStatement expr = (TableStatement) CCJSqlParserUtil + .parse("TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10"); + assertEquals("TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10", expr.toString()); + } + @Test public void testCondExpressionIssue1482_2() throws JSQLParserException { Expression expr = CCJSqlParserUtil.parseCondExpression( @@ -383,7 +389,7 @@ public void run() { assertDoesNotThrow(new Executable() { @Override public void execute() throws Throwable { - executorService.awaitTermination(10, TimeUnit.SECONDS); + executorService.awaitTermination(20, TimeUnit.SECONDS); } }); diff --git a/src/test/java/net/sf/jsqlparser/parser/ParserKeywordsUtilsTest.java b/src/test/java/net/sf/jsqlparser/parser/ParserKeywordsUtilsTest.java index c48b3ef11..b1e9ed937 100644 --- a/src/test/java/net/sf/jsqlparser/parser/ParserKeywordsUtilsTest.java +++ b/src/test/java/net/sf/jsqlparser/parser/ParserKeywordsUtilsTest.java @@ -23,7 +23,6 @@ import org.javacc.parser.RegularExpression; import org.javacc.parser.Semanticize; import org.javacc.parser.Token; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -40,7 +39,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.logging.Logger; -import org.junit.jupiter.api.Disabled; +import org.javacc.parser.JavaCCErrors; class ParserKeywordsUtilsTest { @@ -61,39 +60,41 @@ private static void addTokenImage(TreeSet allKeywords, Object o) throws if (o instanceof RStringLiteral) { RStringLiteral literal = (RStringLiteral) o; addTokenImage(allKeywords, literal); - } else if (o instanceof RChoice) { + } else if (o instanceof RChoice) { RChoice choice = (RChoice) o; addTokenImage(allKeywords, choice); } else if (o instanceof RSequence) { RSequence sequence1 = (RSequence) o; addTokenImage(allKeywords, sequence1); - } else if (o instanceof ROneOrMore) { - ROneOrMore oneOrMore = (ROneOrMore) o ; + } else if (o instanceof ROneOrMore) { + ROneOrMore oneOrMore = (ROneOrMore) o; addTokenImage(allKeywords, oneOrMore); - } else if (o instanceof RZeroOrMore) { - RZeroOrMore zeroOrMore = (RZeroOrMore) o ; + } else if (o instanceof RZeroOrMore) { + RZeroOrMore zeroOrMore = (RZeroOrMore) o; addTokenImage(allKeywords, zeroOrMore); - } else if (o instanceof RZeroOrOne) { - RZeroOrOne zeroOrOne = (RZeroOrOne) o ; + } else if (o instanceof RZeroOrOne) { + RZeroOrOne zeroOrOne = (RZeroOrOne) o; addTokenImage(allKeywords, zeroOrOne); - } else if (o instanceof RJustName) { - RJustName zeroOrOne = (RJustName) o ; + } else if (o instanceof RJustName) { + RJustName zeroOrOne = (RJustName) o; addTokenImage(allKeywords, zeroOrOne); - } else if (o instanceof RCharacterList) { + } else if (o instanceof RCharacterList) { // do nothing, we are not interested in those } else { - throw new InvalidClassException("Unknown Type: " + o.getClass().getName() + " " + o.toString()); + throw new InvalidClassException( + "Unknown Type: " + o.getClass().getName() + " " + o.toString()); } } - private static void addTokenImage(TreeSet allKeywords, RSequence sequence) throws Exception { - for (Object o: sequence.units) { + private static void addTokenImage(TreeSet allKeywords, RSequence sequence) + throws Exception { + for (Object o : sequence.units) { addTokenImage(allKeywords, o); } } private static void addTokenImage(TreeSet allKeywords, ROneOrMore oneOrMore) { - for (Token token: oneOrMore.lhsTokens) { + for (Token token : oneOrMore.lhsTokens) { if (CHARSET_ENCODER.canEncode(token.image)) { allKeywords.add(token.image); } @@ -101,7 +102,7 @@ private static void addTokenImage(TreeSet allKeywords, ROneOrMore oneOrM } private static void addTokenImage(TreeSet allKeywords, RZeroOrMore oneOrMore) { - for (Token token: oneOrMore.lhsTokens) { + for (Token token : oneOrMore.lhsTokens) { if (CHARSET_ENCODER.canEncode(token.image)) { allKeywords.add(token.image); } @@ -109,7 +110,7 @@ private static void addTokenImage(TreeSet allKeywords, RZeroOrMore oneOr } private static void addTokenImage(TreeSet allKeywords, RZeroOrOne oneOrMore) { - for (Token token: oneOrMore.lhsTokens) { + for (Token token : oneOrMore.lhsTokens) { if (CHARSET_ENCODER.canEncode(token.image)) { allKeywords.add(token.image); } @@ -117,15 +118,16 @@ private static void addTokenImage(TreeSet allKeywords, RZeroOrOne oneOrM } private static void addTokenImage(TreeSet allKeywords, RJustName oneOrMore) { - for (Token token: oneOrMore.lhsTokens) { + for (Token token : oneOrMore.lhsTokens) { if (CHARSET_ENCODER.canEncode(token.image)) { allKeywords.add(token.image); } } } - private static void addTokenImage(TreeSet allKeywords, RChoice choice) throws Exception { - for (Object o: choice.getChoices()) { + private static void addTokenImage(TreeSet allKeywords, RChoice choice) + throws Exception { + for (Object o : choice.getChoices()) { addTokenImage(allKeywords, o); } } @@ -136,7 +138,7 @@ public static TreeSet getAllKeywordsUsingJavaCC(File file) throws Except Path jjtGrammar = file.toPath(); Path jjGrammarOutputDir = Files.createTempDirectory("jjgrammer"); - new JJTree().main(new String[]{ + new JJTree().main(new String[] { "-JDK_VERSION=1.8", "-OUTPUT_DIRECTORY=" + jjGrammarOutputDir.toString(), jjtGrammar.toString() @@ -147,14 +149,16 @@ public static TreeSet getAllKeywordsUsingJavaCC(File file) throws Except parser.javacc_input(); // needed for filling JavaCCGlobals + JavaCCErrors.reInit(); Semanticize.start(); // read all the Token and get the String image - for (Map.Entry item : JavaCCGlobals.rexps_of_tokens.entrySet()) { + for (Map.Entry item : JavaCCGlobals.rexps_of_tokens + .entrySet()) { addTokenImage(allKeywords, item.getValue()); } - //clean up + // clean up if (jjGrammarOutputDir.toFile().exists()) { jjGrammarOutputDir.toFile().delete(); } @@ -164,38 +168,37 @@ public static TreeSet getAllKeywordsUsingJavaCC(File file) throws Except @Test void getAllKeywords() throws IOException { - Set allKeywords = ParserKeywordsUtils.getAllKeywordsUsingRegex(FILE); - Assertions.assertFalse( allKeywords.isEmpty(), "Keyword List must not be empty!" ); + Set allKeywords = ParserKeywordsUtils.getAllKeywordsUsingRegex(FILE); + Assertions.assertFalse(allKeywords.isEmpty(), "Keyword List must not be empty!"); } @Test - @Disabled void getAllKeywordsUsingJavaCC() throws Exception { - Set allKeywords = getAllKeywordsUsingJavaCC(FILE); - Assertions.assertFalse( allKeywords.isEmpty(), "Keyword List must not be empty!" ); + Set allKeywords = getAllKeywordsUsingJavaCC(FILE); + Assertions.assertFalse(allKeywords.isEmpty(), "Keyword List must not be empty!"); } // Test, if all Tokens found per RegEx are also found from the JavaCCParser @Test - @Disabled void compareKeywordLists() throws Exception { - Set allRegexKeywords = ParserKeywordsUtils.getAllKeywordsUsingRegex(FILE); - Set allJavaCCParserKeywords = getAllKeywordsUsingJavaCC(FILE); + Set allRegexKeywords = ParserKeywordsUtils.getAllKeywordsUsingRegex(FILE); + Set allJavaCCParserKeywords = getAllKeywordsUsingJavaCC(FILE); // Exceptions, which should not have been found from the RegEx List exceptions = Arrays.asList("0x"); // We expect all Keywords from the Regex to be found by the JavaCC Parser - for (String s:allRegexKeywords) { + for (String s : allRegexKeywords) { Assertions.assertTrue( - exceptions.contains(s) || allJavaCCParserKeywords.contains(s) - , "The Keywords from JavaCC do not contain Keyword: " + s); + exceptions.contains(s) || allJavaCCParserKeywords.contains(s), + "The Keywords from JavaCC do not contain Keyword: " + s); } - // The JavaCC Parser finds some more valid Keywords (where no explicit Token has been defined - for (String s:allJavaCCParserKeywords) { - if ( ! (exceptions.contains(s) || allRegexKeywords.contains(s)) ) { - LOGGER.fine ("Found Additional Keywords from Parser: " + s); + // The JavaCC Parser finds some more valid Keywords (where no explicit Token has been + // defined + for (String s : allJavaCCParserKeywords) { + if (!(exceptions.contains(s) || allRegexKeywords.contains(s))) { + LOGGER.fine("Found Additional Keywords from Parser: " + s); } } } diff --git a/src/test/java/net/sf/jsqlparser/statement/DescribeTest.java b/src/test/java/net/sf/jsqlparser/statement/DescribeTest.java index 204b886c4..a81a368a5 100644 --- a/src/test/java/net/sf/jsqlparser/statement/DescribeTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/DescribeTest.java @@ -9,8 +9,9 @@ */ package net.sf.jsqlparser.statement; -import net.sf.jsqlparser.JSQLParserException; import static net.sf.jsqlparser.test.TestUtils.*; + +import net.sf.jsqlparser.JSQLParserException; import org.junit.jupiter.api.Test; public class DescribeTest { @@ -20,6 +21,12 @@ public void testDescribe() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("DESCRIBE foo.products"); } + @Test + public void testDescribeIssue1931() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("DESC table_name"); + assertSqlCanBeParsedAndDeparsed("EXPLAIN table_name"); + } + @Test public void testDescribeIssue1212() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("DESCRIBE file_azbs.productcategory.json"); diff --git a/src/test/java/net/sf/jsqlparser/statement/RefreshMaterializedViewStatementTest.java b/src/test/java/net/sf/jsqlparser/statement/RefreshMaterializedViewStatementTest.java new file mode 100644 index 000000000..4ebba56c7 --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/statement/RefreshMaterializedViewStatementTest.java @@ -0,0 +1,28 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2019 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement; + +import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; + +import net.sf.jsqlparser.JSQLParserException; +import org.junit.jupiter.api.Test; + +/** + * + * @author jxnu-liguobin + */ + +public class RefreshMaterializedViewStatementTest { + + @Test + public void testSimpleUse() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("REFRESH MATERIALIZED VIEW my_view"); + } +} diff --git a/src/test/java/net/sf/jsqlparser/statement/StatementSeparatorTest.java b/src/test/java/net/sf/jsqlparser/statement/StatementSeparatorTest.java index ce92cdd26..b99ee6f26 100644 --- a/src/test/java/net/sf/jsqlparser/statement/StatementSeparatorTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/StatementSeparatorTest.java @@ -21,7 +21,7 @@ void testDoubleNewLine() throws JSQLParserException { String sqlStr = "SELECT * FROM DUAL\n\n\nSELECT * FROM DUAL\n\n\n\nSELECT * FROM dual\n\n\n\n\nSELECT * FROM dual"; Statements statements = CCJSqlParserUtil.parseStatements(sqlStr); - Assertions.assertEquals(4, statements.getStatements().size()); + Assertions.assertEquals(4, statements.size()); } @Test @@ -29,7 +29,7 @@ void testNewLineSlash() throws JSQLParserException { String sqlStr = "SELECT * FROM DUAL\n\n\nSELECT * FROM DUAL\n/\nSELECT * FROM dual\n/\n\nSELECT * FROM dual"; Statements statements = CCJSqlParserUtil.parseStatements(sqlStr); - Assertions.assertEquals(4, statements.getStatements().size()); + Assertions.assertEquals(4, statements.size()); } @Test @@ -37,7 +37,15 @@ void testNewLineGo() throws JSQLParserException { String sqlStr = "SELECT * FROM DUAL\n\n\nSELECT * FROM DUAL\nGO\nSELECT * FROM dual\ngo\n\nSELECT * FROM dual\ngo"; Statements statements = CCJSqlParserUtil.parseStatements(sqlStr); - Assertions.assertEquals(4, statements.getStatements().size()); + Assertions.assertEquals(4, statements.size()); + } + + @Test + void testNewLineNotGoIssue() throws JSQLParserException { + String sqlStr = + "select name,\ngoods from test_table"; + Statements statements = CCJSqlParserUtil.parseStatements(sqlStr); + Assertions.assertEquals(1, statements.size()); } @Test @@ -52,6 +60,6 @@ void testMSSQLBlock() throws JSQLParserException { String sqlStr = "create view MyView1 as\n" + "select Id,Name from table1\n" + "go\n" + "create view MyView2 as\n" + "select Id,Name from table1\n" + "go"; Statements statements = CCJSqlParserUtil.parseStatements(sqlStr); - Assertions.assertEquals(2, statements.getStatements().size()); + Assertions.assertEquals(2, statements.size()); } } diff --git a/src/test/java/net/sf/jsqlparser/statement/UnsupportedStatementTest.java b/src/test/java/net/sf/jsqlparser/statement/UnsupportedStatementTest.java index 1a7238b6b..c07a0b996 100644 --- a/src/test/java/net/sf/jsqlparser/statement/UnsupportedStatementTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/UnsupportedStatementTest.java @@ -9,6 +9,9 @@ */ package net.sf.jsqlparser.statement; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.select.Select; @@ -17,9 +20,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - public class UnsupportedStatementTest { @Test public void testSingleUnsupportedStatement() throws JSQLParserException { @@ -88,6 +88,13 @@ void testAlter() throws JSQLParserException { assertTrue(statement instanceof UnsupportedStatement); } + @Test + void testRefresh() throws JSQLParserException { + String sqlStr = "REFRESH MATERIALIZED VIEW CONCURRENTLY my_view WITH NO DATA"; + Statements statement = CCJSqlParserUtil.parseStatements(sqlStr); + assertTrue(statement.get(0) instanceof UnsupportedStatement); + } + @Test void testCreate() throws JSQLParserException { String sqlStr = diff --git a/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java b/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java index 0bc241766..ab07437a6 100644 --- a/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java @@ -9,10 +9,16 @@ */ package net.sf.jsqlparser.statement.alter; +import static net.sf.jsqlparser.test.TestUtils.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.Arrays; import java.util.Collections; import java.util.List; - import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.StringValue; import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo; @@ -30,20 +36,14 @@ import net.sf.jsqlparser.statement.create.table.Index; import net.sf.jsqlparser.statement.create.table.Index.ColumnParams; import net.sf.jsqlparser.statement.create.table.NamedConstraint; -import static net.sf.jsqlparser.test.TestUtils.*; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; public class AlterTest { @Test public void testAlterTableAddColumn() throws JSQLParserException { - Statement stmt = CCJSqlParserUtil. - parse("ALTER TABLE mytable ADD COLUMN mycolumn varchar (255)"); + Statement stmt = + CCJSqlParserUtil.parse("ALTER TABLE mytable ADD COLUMN mycolumn varchar (255)"); assertTrue(stmt instanceof Alter); Alter alter = (Alter) stmt; assertEquals("mytable", alter.getTable().getFullyQualifiedName()); @@ -69,19 +69,32 @@ public void testAlterTableAddColumn_ColumnKeyWordImplicit() throws JSQLParserExc @Test - public void testAlterTableBackBrackets()throws JSQLParserException{ - String sql="ALTER TABLE tablename add column (field string comment 'aaaaa')"; + public void testAlterTableBackBrackets() throws JSQLParserException { + String sql = "ALTER TABLE tablename add column (field string comment 'aaaaa')"; Statement statement = CCJSqlParserUtil.parse(sql); - Alter alter=(Alter) statement; + Alter alter = (Alter) statement; System.out.println(alter.toString()); - String sql2="ALTER TABLE tablename add column (field string comment 'aaaaa', field2 string comment 'bbbbb');"; + String sql2 = + "ALTER TABLE tablename add column (field string comment 'aaaaa', field2 string comment 'bbbbb');"; Statement statement2 = CCJSqlParserUtil.parse(sql2); - Alter alter2=(Alter) statement2; + Alter alter2 = (Alter) statement2; System.out.println(alter2.toString()); } + @Test + public void testAlterTableIssue1815() throws JSQLParserException { + // MySQL: see https://dev.mysql.com/doc/refman/8.0/en/alter-table.html + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE cers_record_10 RENAME INDEX idx_cers_record_1_gmtcreate TO idx_cers_record_10_gmtcreate"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE cers_record_10 RENAME KEY k_cers_record_1_gmtcreate TO k_cers_record_10_gmtcreate"); + // PostgreSQL: see https://www.postgresql.org/docs/current/sql-altertable.html + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE cers_record_10 RENAME CONSTRAINT cst_cers_record_1_gmtcreate TO cst_cers_record_10_gmtcreate"); + } + @Test public void testAlterTablePrimaryKey() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("ALTER TABLE animals ADD PRIMARY KEY (id)"); @@ -109,37 +122,44 @@ public void testAlterTablePrimaryKeyNoValidate() throws JSQLParserException { @Test public void testAlterTablePrimaryKeyDeferrableValidate() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE animals ADD PRIMARY KEY (id) DEFERRABLE VALIDATE"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE animals ADD PRIMARY KEY (id) DEFERRABLE VALIDATE"); } @Test public void testAlterTablePrimaryKeyDeferrableDisableNoValidate() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE animals ADD PRIMARY KEY (id) DEFERRABLE DISABLE NOVALIDATE"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE animals ADD PRIMARY KEY (id) DEFERRABLE DISABLE NOVALIDATE"); } @Test public void testAlterTableUniqueKey() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE `schema_migrations` ADD UNIQUE KEY `unique_schema_migrations` (`version`)"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE `schema_migrations` ADD UNIQUE KEY `unique_schema_migrations` (`version`)"); } @Test public void testAlterTableForgeignKey() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES ra_user (id) ON DELETE CASCADE"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES ra_user (id) ON DELETE CASCADE"); } @Test public void testAlterTableAddConstraint() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE RESOURCELINKTYPE ADD CONSTRAINT FK_RESOURCELINKTYPE_PARENTTYPE_PRIMARYKEY FOREIGN KEY (PARENTTYPE_PRIMARYKEY) REFERENCES RESOURCETYPE(PRIMARYKEY)"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE RESOURCELINKTYPE ADD CONSTRAINT FK_RESOURCELINKTYPE_PARENTTYPE_PRIMARYKEY FOREIGN KEY (PARENTTYPE_PRIMARYKEY) REFERENCES RESOURCETYPE(PRIMARYKEY)"); } @Test public void testAlterTableAddConstraintWithConstraintState() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE RESOURCELINKTYPE ADD CONSTRAINT FK_RESOURCELINKTYPE_PARENTTYPE_PRIMARYKEY FOREIGN KEY (PARENTTYPE_PRIMARYKEY) REFERENCES RESOURCETYPE(PRIMARYKEY) DEFERRABLE DISABLE NOVALIDATE"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE RESOURCELINKTYPE ADD CONSTRAINT FK_RESOURCELINKTYPE_PARENTTYPE_PRIMARYKEY FOREIGN KEY (PARENTTYPE_PRIMARYKEY) REFERENCES RESOURCETYPE(PRIMARYKEY) DEFERRABLE DISABLE NOVALIDATE"); } @Test public void testAlterTableAddConstraintWithConstraintState2() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE RESOURCELINKTYPE ADD CONSTRAINT RESOURCELINKTYPE_PRIMARYKEY PRIMARY KEY (PRIMARYKEY) DEFERRABLE NOVALIDATE"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE RESOURCELINKTYPE ADD CONSTRAINT RESOURCELINKTYPE_PRIMARYKEY PRIMARY KEY (PRIMARYKEY) DEFERRABLE NOVALIDATE"); } @Test @@ -149,24 +169,28 @@ public void testAlterTableAddUniqueConstraint() throws JSQLParserException { @Test public void testAlterTableForeignKey2() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES ra_user (id)"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES ra_user (id)"); } @Test public void testAlterTableForeignKey3() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES ra_user (id) ON DELETE RESTRICT"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES ra_user (id) ON DELETE RESTRICT"); } @Test public void testAlterTableForeignKey4() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES ra_user (id) ON DELETE SET NULL"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES ra_user (id) ON DELETE SET NULL"); } @Test public void testAlterTableForeignWithFkSchema() throws JSQLParserException { final String FK_SCHEMA_NAME = "my_schema"; final String FK_TABLE_NAME = "ra_user"; - String sql = "ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES " + FK_SCHEMA_NAME + "." + FK_TABLE_NAME + " (id) ON DELETE SET NULL"; + String sql = "ALTER TABLE test ADD FOREIGN KEY (user_id) REFERENCES " + FK_SCHEMA_NAME + "." + + FK_TABLE_NAME + " (id) ON DELETE SET NULL"; assertSqlCanBeParsedAndDeparsed(sql); Alter alter = (Alter) CCJSqlParserUtil.parse(sql); @@ -176,6 +200,12 @@ public void testAlterTableForeignWithFkSchema() throws JSQLParserException { assertEquals(alterExpression.getFkSourceTable(), FK_TABLE_NAME); } + @Test + public void testAlterTableDropKey() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE ANV_ALERT_ACKNOWLEDGE_TYPE DROP KEY ALERT_ACKNOWLEDGE_TYPE_ID_NUK_1"); + } + @Test public void testAlterTableDropColumn() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("ALTER TABLE test DROP COLUMN YYY"); @@ -185,8 +215,8 @@ public void testAlterTableDropColumn() throws JSQLParserException { public void testAlterTableDropColumn2() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("ALTER TABLE mytable DROP COLUMN col1, DROP COLUMN col2"); - Statement stmt = CCJSqlParserUtil. - parse("ALTER TABLE mytable DROP COLUMN col1, DROP COLUMN col2"); + Statement stmt = + CCJSqlParserUtil.parse("ALTER TABLE mytable DROP COLUMN col1, DROP COLUMN col2"); Alter alter = (Alter) stmt; List alterExps = alter.getAlterExpressions(); AlterExpression col1Exp = alterExps.get(0); @@ -216,7 +246,7 @@ public void testAlterTablePK() throws JSQLParserException { assertStatementCanBeDeparsedAs(stmt, sql); AlterExpression alterExpression = ((Alter) stmt).getAlterExpressions().get(0); assertNull(alterExpression.getConstraintName()); - // TODO: should this pass? ==> assertEquals(alterExpression.getPkColumns().get(0), "ID"); + // TODO: should this pass? ==> assertEquals(alterExpression.getPkColumns().get(0), "ID"); assertEquals(alterExpression.getIndex().getColumnsNames().get(0), "`ID`"); } @@ -235,14 +265,17 @@ public void testAlterTableFK() throws JSQLParserException { @Test public void testAlterTableCheckConstraint() throws JSQLParserException { - String statement = "ALTER TABLE `Author` ADD CONSTRAINT name_not_empty CHECK (`NAME` <> '')"; + String statement = + "ALTER TABLE `Author` ADD CONSTRAINT name_not_empty CHECK (`NAME` <> '')"; Statement parsed = assertSqlCanBeParsedAndDeparsed(statement); Alter created = new Alter().withTable(new Table("`Author`")) .addAlterExpressions(Collections.singleton( - new AlterExpression().withOperation(AlterOperation.ADD).withIndex(new CheckConstraint() - .withName("name_not_empty") - .withExpression(new NotEqualsTo().withLeftExpression(new Column("`NAME`")) - .withRightExpression(new StringValue()))))); + new AlterExpression().withOperation(AlterOperation.ADD) + .withIndex(new CheckConstraint() + .withName("name_not_empty") + .withExpression(new NotEqualsTo() + .withLeftExpression(new Column("`NAME`")) + .withRightExpression(new StringValue()))))); assertDeparse(created, statement); assertEqualsObjectTree(parsed, created); } @@ -259,10 +292,11 @@ public void testAlterTableAddColumn3() throws JSQLParserException { @Test public void testAlterTableAddColumn4() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE mytable ADD COLUMN col1 varchar (255), ADD COLUMN col2 integer"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE mytable ADD COLUMN col1 varchar (255), ADD COLUMN col2 integer"); - Statement stmt = CCJSqlParserUtil. - parse("ALTER TABLE mytable ADD COLUMN col1 varchar (255), ADD COLUMN col2 integer"); + Statement stmt = CCJSqlParserUtil.parse( + "ALTER TABLE mytable ADD COLUMN col1 varchar (255), ADD COLUMN col2 integer"); Alter alter = (Alter) stmt; List alterExps = alter.getAlterExpressions(); AlterExpression col1Exp = alterExps.get(0); @@ -308,12 +342,14 @@ public void testAlterTableAddColumn6() throws JSQLParserException { @Test public void testAlterTableModifyColumn1() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE animals MODIFY (col1 integer, col2 number (8, 2))"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE animals MODIFY (col1 integer, col2 number (8, 2))"); } @Test public void testAlterTableModifyColumn2() throws JSQLParserException { - Alter alter = (Alter) CCJSqlParserUtil.parse("ALTER TABLE mytable modify col1 timestamp (6)"); + Alter alter = + (Alter) CCJSqlParserUtil.parse("ALTER TABLE mytable modify col1 timestamp (6)"); AlterExpression alterExpression = alter.getAlterExpressions().get(0); // COLUMN keyword DOES NOT appear in deparsed statement, modify becomes all caps @@ -327,7 +363,8 @@ public void testAlterTableModifyColumn2() throws JSQLParserException { @Test public void testAlterTableAlterColumn() throws JSQLParserException { // http://www.postgresqltutorial.com/postgresql-change-column-type/ - String sql = "ALTER TABLE table_name ALTER COLUMN column_name_1 TYPE TIMESTAMP, ALTER COLUMN column_name_2 TYPE BOOLEAN"; + String sql = + "ALTER TABLE table_name ALTER COLUMN column_name_1 TYPE TIMESTAMP, ALTER COLUMN column_name_2 TYPE BOOLEAN"; assertSqlCanBeParsedAndDeparsed(sql); Alter alter = (Alter) CCJSqlParserUtil.parse(sql); @@ -368,13 +405,16 @@ public void testAlterTableChangeColumn4() throws JSQLParserException { @Test public void testAlterTableAddColumnWithZone() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE mytable ADD COLUMN col1 timestamp with time zone"); - assertSqlCanBeParsedAndDeparsed("ALTER TABLE mytable ADD COLUMN col1 timestamp without time zone"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE mytable ADD COLUMN col1 timestamp with time zone"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE mytable ADD COLUMN col1 timestamp without time zone"); assertSqlCanBeParsedAndDeparsed("ALTER TABLE mytable ADD COLUMN col1 date with time zone"); - assertSqlCanBeParsedAndDeparsed("ALTER TABLE mytable ADD COLUMN col1 date without time zone"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE mytable ADD COLUMN col1 date without time zone"); - Statement stmt = CCJSqlParserUtil. - parse("ALTER TABLE mytable ADD COLUMN col1 timestamp with time zone"); + Statement stmt = CCJSqlParserUtil + .parse("ALTER TABLE mytable ADD COLUMN col1 timestamp with time zone"); Alter alter = (Alter) stmt; List alterExps = alter.getAlterExpressions(); AlterExpression col1Exp = alterExps.get(0); @@ -414,78 +454,111 @@ public void testAddConstraintKeyIssue320() throws JSQLParserException { String constraintName2 = "table1_constraint_2"; for (String constraintType : Arrays.asList("UNIQUE KEY", "KEY")) { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE " + tableName + " ADD CONSTRAINT " + constraintName1 + " " - + constraintType + " (" + columnName1 + ")"); - - assertSqlCanBeParsedAndDeparsed("ALTER TABLE " + tableName + " ADD CONSTRAINT " + constraintName1 + " " - + constraintType + " (" + columnName1 + ", " + columnName2 + ")"); - - assertSqlCanBeParsedAndDeparsed("ALTER TABLE " + tableName + " ADD CONSTRAINT " + constraintName1 + " " - + constraintType + " (" + columnName1 + ", " + columnName2 + "), ADD CONSTRAINT " - + constraintName2 + " " + constraintType + " (" + columnName3 + ", " + columnName4 + ")"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE " + tableName + " ADD CONSTRAINT " + constraintName1 + " " + + constraintType + " (" + columnName1 + ")"); + + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE " + tableName + " ADD CONSTRAINT " + constraintName1 + " " + + constraintType + " (" + columnName1 + ", " + columnName2 + ")"); + + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE " + tableName + " ADD CONSTRAINT " + constraintName1 + " " + + constraintType + " (" + columnName1 + ", " + columnName2 + + "), ADD CONSTRAINT " + + constraintName2 + " " + constraintType + " (" + columnName3 + ", " + + columnName4 + ")"); } } @Test public void testIssue633() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE team_phases ADD CONSTRAINT team_phases_id_key UNIQUE (id)"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE team_phases ADD CONSTRAINT team_phases_id_key UNIQUE (id)"); } @Test public void testIssue679() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE tb_session_status ADD INDEX idx_user_id_name (user_id, user_name(10)), ADD INDEX idx_user_name (user_name)"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE tb_session_status ADD INDEX idx_user_id_name (user_id, user_name(10)), ADD INDEX idx_user_name (user_name)"); + } + + @Test + public void testAlterTableColumnCommentIssue1926() throws JSQLParserException { + String statement = + "ALTER TABLE `student` ADD INDEX `idx_age` (`age`) USING BTREE COMMENT 'index age'"; + assertSqlCanBeParsedAndDeparsed(statement); + + String stmt2 = + "ALTER TABLE `student` ADD INDEX `idx_name` (`name`) COMMENT 'index name', " + + "ADD INDEX `idx_age` (`age`) USING BTREE COMMENT 'index age'"; + assertSqlCanBeParsedAndDeparsed(stmt2); + + // TODO NOT SUPPORT MYSQL: ADD {INDEX | KEY} `idx_age` USING BTREE (`age`) + // String stmt3 = "ALTER TABLE `student` ADD INDEX `idx_age` USING BTREE (`age`) COMMENT + // 'index age'"; + // assertSqlCanBeParsedAndDeparsed(stmt3); } @Test public void testAlterTableIndex586() throws Exception { - Statement result = CCJSqlParserUtil.parse("ALTER TABLE biz_add_fee DROP INDEX operation_time, " - + "ADD UNIQUE INDEX operation_time (`operation_time`, `warehouse_code`, `customerid`, `fees_type`, `external_no`) " - + "USING BTREE, ALGORITHM = INPLACE"); - assertEquals("ALTER TABLE biz_add_fee DROP INDEX operation_time , " + Statement result = + CCJSqlParserUtil.parse("ALTER TABLE biz_add_fee DROP INDEX operation_time, " + + "ADD UNIQUE INDEX operation_time (`operation_time`, `warehouse_code`, `customerid`, `fees_type`, `external_no`) " + + "USING BTREE, ALGORITHM = INPLACE"); + assertEquals("ALTER TABLE biz_add_fee DROP INDEX operation_time, " + "ADD UNIQUE INDEX operation_time (`operation_time`, `warehouse_code`, `customerid`, `fees_type`, `external_no`) " + "USING BTREE, ALGORITHM = INPLACE", result.toString()); } @Test public void testIssue259() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE feature_v2 ADD COLUMN third_user_id int (10) unsigned DEFAULT '0' COMMENT '第三方用户id' after kdt_id"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE feature_v2 ADD COLUMN third_user_id int (10) unsigned DEFAULT '0' COMMENT '第三方用户id' after kdt_id"); } @Test public void testIssue633_2() throws JSQLParserException { - String statement = "CREATE INDEX idx_american_football_action_plays_1 ON american_football_action_plays USING btree (play_type)"; + String statement = + "CREATE INDEX idx_american_football_action_plays_1 ON american_football_action_plays USING btree (play_type)"; Statement parsed = assertSqlCanBeParsedAndDeparsed(statement); CreateIndex created = new CreateIndex() .withTable(new Table("american_football_action_plays")) .withIndex( new Index().withName("idx_american_football_action_plays_1") - .addColumns(new ColumnParams("play_type", null)).withUsing("btree") - ); + .addColumns(new ColumnParams("play_type", null)) + .withUsing("btree")); assertDeparse(created, statement); assertEqualsObjectTree(parsed, created); } @Test public void testAlterOnlyIssue928() throws JSQLParserException { - String statement = "ALTER TABLE ONLY categories ADD CONSTRAINT pk_categories PRIMARY KEY (category_id)"; + String statement = + "ALTER TABLE ONLY categories ADD CONSTRAINT pk_categories PRIMARY KEY (category_id)"; Statement parsed = assertSqlCanBeParsedAndDeparsed(statement); - Alter created = new Alter().withUseOnly(true).withTable(new Table("categories")).addAlterExpressions( - new AlterExpression().withOperation(AlterOperation.ADD).withIndex(new NamedConstraint() - .withName(Collections.singletonList( - "pk_categories")).withType("PRIMARY KEY") - .addColumns(new ColumnParams("category_id")))); + Alter created = new Alter().withUseOnly(true).withTable(new Table("categories")) + .addAlterExpressions( + new AlterExpression().withOperation(AlterOperation.ADD) + .withIndex(new NamedConstraint() + .withName(Collections.singletonList( + "pk_categories")) + .withType("PRIMARY KEY") + .addColumns(new ColumnParams("category_id")))); assertDeparse(created, statement); assertEqualsObjectTree(parsed, created); } @Test public void testAlterConstraintWithoutFKSourceColumnsIssue929() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE orders ADD CONSTRAINT fk_orders_customers FOREIGN KEY (customer_id) REFERENCES customers"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE orders ADD CONSTRAINT fk_orders_customers FOREIGN KEY (customer_id) REFERENCES customers"); } @Test public void testAlterTableAlterColumnDropNotNullIssue918() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE \"user_table_t\" ALTER COLUMN name DROP NOT NULL"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE \"user_table_t\" ALTER COLUMN name DROP NOT NULL"); } @Test @@ -509,15 +582,15 @@ public void testAlterTableRenameColumn() throws JSQLParserException { public void testAlterTableForeignKeyIssue981() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed( "ALTER TABLE atconfigpro " - + "ADD CONSTRAINT atconfigpro_atconfignow_id_foreign FOREIGN KEY (atconfignow_id) REFERENCES atconfignow(id) ON DELETE CASCADE, " - + "ADD CONSTRAINT atconfigpro_attariff_id_foreign FOREIGN KEY (attariff_id) REFERENCES attariff(id) ON DELETE CASCADE"); + + "ADD CONSTRAINT atconfigpro_atconfignow_id_foreign FOREIGN KEY (atconfignow_id) REFERENCES atconfignow(id) ON DELETE CASCADE, " + + "ADD CONSTRAINT atconfigpro_attariff_id_foreign FOREIGN KEY (attariff_id) REFERENCES attariff(id) ON DELETE CASCADE"); } @Test public void testAlterTableForeignKeyIssue981_2() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed( "ALTER TABLE atconfigpro " - + "ADD CONSTRAINT atconfigpro_atconfignow_id_foreign FOREIGN KEY (atconfignow_id) REFERENCES atconfignow(id) ON DELETE CASCADE"); + + "ADD CONSTRAINT atconfigpro_atconfignow_id_foreign FOREIGN KEY (atconfignow_id) REFERENCES atconfignow(id) ON DELETE CASCADE"); } @Test @@ -537,7 +610,8 @@ public void testAlterTableColumnCommentIssue984() throws JSQLParserException { Statement parsed = assertSqlCanBeParsedAndDeparsed( statement); Alter created = new Alter().withTable(new Table("texto_fichero")) - .addAlterExpressions(new AlterExpression().withOperation(AlterOperation.MODIFY).withColumnName("id") + .addAlterExpressions(new AlterExpression().withOperation(AlterOperation.MODIFY) + .withColumnName("id") .withCommentText("'some comment'")); assertDeparse(created, statement); assertEqualsObjectTree(parsed, created); @@ -713,10 +787,12 @@ public void testIssue985_2() throws JSQLParserException { @Test public void testAlterTableDefaultValueTrueIssue926() throws JSQLParserException { - Alter parsed = (Alter) CCJSqlParserUtil.parse("ALTER TABLE my_table ADD some_column BOOLEAN DEFAULT FALSE"); + Alter parsed = (Alter) CCJSqlParserUtil + .parse("ALTER TABLE my_table ADD some_column BOOLEAN DEFAULT FALSE"); // There shall be no COLUMN where there is no COLUMN - assertStatementCanBeDeparsedAs(parsed, "ALTER TABLE my_table ADD some_column BOOLEAN DEFAULT FALSE"); + assertStatementCanBeDeparsedAs(parsed, + "ALTER TABLE my_table ADD some_column BOOLEAN DEFAULT FALSE"); } private void assertReferentialActionOnConstraint(Alter parsed, Action onUpdate, @@ -727,7 +803,8 @@ private void assertReferentialActionOnConstraint(Alter parsed, Action onUpdate, // remove line if deprecated methods are removed. index.setOnDeleteReferenceOption(index.getOnDeleteReferenceOption()); if (onDelete != null) { - assertEquals(new ReferentialAction(Type.DELETE, onDelete), index.getReferentialAction(Type.DELETE)); + assertEquals(new ReferentialAction(Type.DELETE, onDelete), + index.getReferentialAction(Type.DELETE)); } else { assertNull(index.getReferentialAction(Type.DELETE)); } @@ -735,7 +812,8 @@ private void assertReferentialActionOnConstraint(Alter parsed, Action onUpdate, // remove line if deprecated methods are removed. index.setOnUpdateReferenceOption(index.getOnUpdateReferenceOption()); if (onUpdate != null) { - assertEquals(new ReferentialAction(Type.UPDATE, onUpdate), index.getReferentialAction(Type.UPDATE)); + assertEquals(new ReferentialAction(Type.UPDATE, onUpdate), + index.getReferentialAction(Type.UPDATE)); } else { assertNull(index.getReferentialAction(Type.UPDATE)); } @@ -779,7 +857,8 @@ public void testRowFormatKeywordIssue1033() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("ALTER TABLE t1 MOVE TABLESPACE users", true); - assertSqlCanBeParsedAndDeparsed("ALTER TABLE test_tab MOVE PARTITION test_tab_q2 COMPRESS", true); + assertSqlCanBeParsedAndDeparsed("ALTER TABLE test_tab MOVE PARTITION test_tab_q2 COMPRESS", + true); } @Test @@ -797,15 +876,19 @@ public void testAlterTableDropConstraintsIssue1342() throws JSQLParserException @Test public void testAlterTableChangeColumnDropNotNull() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("ALTER TABLE a MODIFY COLUMN b DROP NOT NULL", true); - assertSqlCanBeParsedAndDeparsed("ALTER TABLE a MODIFY (COLUMN b DROP NOT NULL, COLUMN c DROP NOT NULL)", true); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE a MODIFY (COLUMN b DROP NOT NULL, COLUMN c DROP NOT NULL)", true); } @Test public void testAlterTableChangeColumnDropDefault() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("ALTER TABLE a MODIFY COLUMN b DROP DEFAULT", true); - assertSqlCanBeParsedAndDeparsed("ALTER TABLE a MODIFY (COLUMN b DROP DEFAULT, COLUMN c DROP DEFAULT)", true); - assertSqlCanBeParsedAndDeparsed("ALTER TABLE a MODIFY (COLUMN b DROP NOT NULL, COLUMN b DROP DEFAULT)", true); - assertSqlCanBeParsedAndDeparsed("ALTER TABLE a MODIFY (COLUMN b DROP DEFAULT, COLUMN b DROP NOT NULL)", true); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE a MODIFY (COLUMN b DROP DEFAULT, COLUMN c DROP DEFAULT)", true); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE a MODIFY (COLUMN b DROP NOT NULL, COLUMN b DROP DEFAULT)", true); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE a MODIFY (COLUMN b DROP DEFAULT, COLUMN b DROP NOT NULL)", true); } @Test @@ -813,20 +896,45 @@ public void testAlterTableDropColumnIfExists() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("ALTER TABLE test DROP COLUMN IF EXISTS name"); } + @Test + public void testAlterTableCommentIssue1935() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("ALTER TABLE table_name COMMENT = 'New table comment'"); + assertSqlCanBeParsedAndDeparsed("ALTER TABLE table_name COMMENT 'New table comment'"); + } + @Test public void testAlterTableDropMultipleColumnsIfExists() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE test DROP COLUMN IF EXISTS name, DROP COLUMN IF EXISTS surname"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE test DROP COLUMN IF EXISTS name, DROP COLUMN IF EXISTS surname"); + } + + @Test + public void testAlterTableAddIndexWithComment1906() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE `student` ADD KEY `idx_name` (`name`) COMMENT 'name'"); + } + + @Test + public void testAlterTableAddIndexWithComment2() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE team_phases ADD CONSTRAINT team_phases_id_key UNIQUE (id) COMMENT 'name'"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE team_phases ADD CONSTRAINT team_phases_id_key UNIQUE KEY (c1, c2) COMMENT 'name'"); + + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE team_phases ADD CONSTRAINT team_phases_id_key PRIMARY KEY (id) COMMENT 'name'"); } @Test public void testAlterTableDropMultipleColumnsIfExistsWithParams() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("ALTER TABLE test DROP COLUMN IF EXISTS name CASCADE, DROP COLUMN IF EXISTS surname CASCADE"); + assertSqlCanBeParsedAndDeparsed( + "ALTER TABLE test DROP COLUMN IF EXISTS name CASCADE, DROP COLUMN IF EXISTS surname CASCADE"); } @Test public void testAlterTableAddColumnSpanner7() throws JSQLParserException { final String sql = "ALTER TABLE ORDER_PATIENT ADD COLUMN FIRST_NAME_UPPERCASE STRING(MAX)" + - " AS (UPPER(FIRST_NAME)) STORED"; + " AS (UPPER(FIRST_NAME)) STORED"; Statement stmt = CCJSqlParserUtil.parse(sql); assertStatementCanBeDeparsedAs(stmt, sql, true); Alter alter = (Alter) stmt; @@ -855,9 +963,11 @@ public void testAlterTableAddColumnSpanner8() throws JSQLParserException { @Test public void testAlterColumnSetCommitTimestamp1() throws JSQLParserException { // @todo: properly implement SET OPTIONS, the current hack is terrible - // final String sql = "ALTER TABLE FOCUS_PATIENT ALTER COLUMN UPDATE_DATE_TIME_GMT SET OPTIONS (allow_commit_timestamp=null)"; + // final String sql = "ALTER TABLE FOCUS_PATIENT ALTER COLUMN UPDATE_DATE_TIME_GMT SET + // OPTIONS (allow_commit_timestamp=null)"; - final String sql = "ALTER TABLE FOCUS_PATIENT ALTER COLUMN UPDATE_DATE_TIME_GMT SET OPTIONS (allow_commit_timestamp=true)"; + final String sql = + "ALTER TABLE FOCUS_PATIENT ALTER COLUMN UPDATE_DATE_TIME_GMT SET OPTIONS (allow_commit_timestamp=true)"; Statement stmt = CCJSqlParserUtil.parse(sql); assertStatementCanBeDeparsedAs(stmt, sql); Alter alter = (Alter) stmt; @@ -868,6 +978,7 @@ public void testAlterColumnSetCommitTimestamp1() throws JSQLParserException { assertEquals(1, col1Exp.getColDataTypeList().size()); ColumnDataType type = col1Exp.getColDataTypeList().get(0); assertEquals("UPDATE_DATE_TIME_GMT", type.getColumnName()); - assertEquals("UPDATE_DATE_TIME_GMT SET OPTIONS (allow_commit_timestamp=true)", type.toString()); + assertEquals("UPDATE_DATE_TIME_GMT SET OPTIONS (allow_commit_timestamp=true)", + type.toString()); } } diff --git a/src/test/java/net/sf/jsqlparser/statement/builder/ReflectionModelTest.java b/src/test/java/net/sf/jsqlparser/statement/builder/ReflectionModelTest.java index 60a1a2d02..75ec41db1 100644 --- a/src/test/java/net/sf/jsqlparser/statement/builder/ReflectionModelTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/builder/ReflectionModelTest.java @@ -9,21 +9,21 @@ */ package net.sf.jsqlparser.statement.builder; +import static net.sf.jsqlparser.test.TestUtils.asList; + +import java.util.ArrayList; +import java.util.List; import net.sf.jsqlparser.expression.AnyType; import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperatorType; import net.sf.jsqlparser.schema.Sequence.ParameterType; import net.sf.jsqlparser.statement.ExplainStatement.OptionType; import net.sf.jsqlparser.statement.create.table.ColDataType; +import net.sf.jsqlparser.statement.refresh.RefreshMode; import net.sf.jsqlparser.statement.select.ParenthesedSelect; import net.sf.jsqlparser.statement.update.UpdateSet; import net.sf.jsqlparser.util.ReflectionTestUtils; import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.List; - -import static net.sf.jsqlparser.test.TestUtils.asList; - /** * Testing of setters, getters, with-/add-methods by calling them with random parameter-values *
    @@ -131,6 +131,8 @@ public class ReflectionModelTest { new net.sf.jsqlparser.statement.SetStatement("name", null), new net.sf.jsqlparser.statement.ShowColumnsStatement(), new net.sf.jsqlparser.statement.show.ShowIndexStatement(), + new net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement( + new net.sf.jsqlparser.schema.Table("my_view"), true, RefreshMode.WITH_DATA), new net.sf.jsqlparser.statement.ShowStatement(), new net.sf.jsqlparser.statement.Statements(), new net.sf.jsqlparser.statement.UseStatement(), diff --git a/src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java b/src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java index a159215b7..23b1d581a 100644 --- a/src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java @@ -9,14 +9,15 @@ */ package net.sf.jsqlparser.statement.create; +import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + import java.io.StringReader; import java.util.List; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserManager; import net.sf.jsqlparser.statement.create.index.CreateIndex; -import static net.sf.jsqlparser.test.TestUtils.*; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; import org.junit.jupiter.api.Test; public class CreateIndexTest { @@ -25,8 +26,7 @@ public class CreateIndexTest { @Test public void testCreateIndex() throws JSQLParserException { - String statement - = "CREATE INDEX myindex ON mytab (mycol, mycol2)"; + String statement = "CREATE INDEX myindex ON mytab (mycol, mycol2)"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(2, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex", createIndex.getIndex().getName()); @@ -38,8 +38,7 @@ public void testCreateIndex() throws JSQLParserException { @Test public void testCreateIndex2() throws JSQLParserException { - String statement - = "CREATE mytype INDEX myindex ON mytab (mycol, mycol2)"; + String statement = "CREATE mytype INDEX myindex ON mytab (mycol, mycol2)"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(2, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex", createIndex.getIndex().getName()); @@ -51,8 +50,7 @@ public void testCreateIndex2() throws JSQLParserException { @Test public void testCreateIndex3() throws JSQLParserException { - String statement - = "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2, mycol3)"; + String statement = "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2, mycol3)"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(3, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex", createIndex.getIndex().getName()); @@ -63,8 +61,7 @@ public void testCreateIndex3() throws JSQLParserException { @Test public void testCreateIndex4() throws JSQLParserException { - String statement - = "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2 (75), mycol3)"; + String statement = "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2 (75), mycol3)"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(3, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex", createIndex.getIndex().getName()); @@ -75,8 +72,8 @@ public void testCreateIndex4() throws JSQLParserException { @Test public void testCreateIndex5() throws JSQLParserException { - String statement - = "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2 (75), mycol3) mymodifiers"; + String statement = + "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2 (75), mycol3) mymodifiers"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(3, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex", createIndex.getIndex().getName()); @@ -93,8 +90,7 @@ public void testCreateIndex6() throws JSQLParserException { @Test public void testCreateIndex7() throws JSQLParserException { - String statement - = "CREATE INDEX myindex1 ON mytab USING GIST (mycol)"; + String statement = "CREATE INDEX myindex1 ON mytab USING GIST (mycol)"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(1, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex1", createIndex.getIndex().getName()); @@ -108,23 +104,25 @@ public void testCreateIndex7() throws JSQLParserException { @Test public void testCreateIndexIssue633() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("CREATE INDEX idx_american_football_action_plays_1 ON american_football_action_plays USING btree (play_type)"); + assertSqlCanBeParsedAndDeparsed( + "CREATE INDEX idx_american_football_action_plays_1 ON american_football_action_plays USING btree (play_type)"); } @Test public void testFullIndexNameIssue936() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("CREATE INDEX \"TS\".\"IDX\" ON \"TEST\" (\"ID\" ASC) TABLESPACE \"TS\""); + assertSqlCanBeParsedAndDeparsed( + "CREATE INDEX \"TS\".\"IDX\" ON \"TEST\" (\"ID\" ASC) TABLESPACE \"TS\""); } @Test public void testFullIndexNameIssue936_2() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("CREATE INDEX \"TS\".\"IDX\" ON \"TEST\" (\"ID\") TABLESPACE \"TS\""); + assertSqlCanBeParsedAndDeparsed( + "CREATE INDEX \"TS\".\"IDX\" ON \"TEST\" (\"ID\") TABLESPACE \"TS\""); } @Test public void testCreateIndexTrailingOptions() throws JSQLParserException { - String statement - = "CREATE UNIQUE INDEX cfe.version_info_idx2\n" + String statement = "CREATE UNIQUE INDEX cfe.version_info_idx2\n" + " ON cfe.version_info ( major_version\n" + " , minor_version\n" + " , patch_level ) parallel compress nologging\n" @@ -136,4 +134,18 @@ public void testCreateIndexTrailingOptions() throws JSQLParserException { assertEquals(tailParameters.get(1), "compress"); assertEquals(tailParameters.get(2), "nologging"); } + + @Test + void testIfNotExistsIssue1861() throws JSQLParserException { + String sqlStr = + "CREATE INDEX IF NOT EXISTS test_test_idx ON test.test USING btree (\"time\")"; + assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } + + @Test + void testCreateIndexIssue1814() throws JSQLParserException { + String sqlStr = + "CREATE INDEX idx_operationlog_operatetime_regioncode USING BTREE ON operation_log (operate_time,region_biz_code)"; + assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } } diff --git a/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java b/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java index fd5b8d3c0..d9c477159 100644 --- a/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java @@ -1043,4 +1043,20 @@ void testCreateTableWithNextValueFor() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed(sqlStr, true); } + @Test + void testIssue1858() throws JSQLParserException { + String sqlStr = "CREATE TABLE \"foo\"\n" + + "(\n" + + " event_sk bigint identity NOT NULL encode RAW\n" + + ") compound sortkey ( date_key )"; + assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } + + @Test + void testIssue1864() throws JSQLParserException { + String sqlStr = "ALTER TABLE `test`.`test_table` " + + "MODIFY COLUMN `test` varchar(251) " + + " CHARACTER SET armscii8 COLLATE armscii8_bin NULL DEFAULT NULL FIRST"; + assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } } diff --git a/src/test/java/net/sf/jsqlparser/statement/create/CreateViewTest.java b/src/test/java/net/sf/jsqlparser/statement/create/CreateViewTest.java index 3499a83be..240a22fc3 100644 --- a/src/test/java/net/sf/jsqlparser/statement/create/CreateViewTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/create/CreateViewTest.java @@ -9,8 +9,13 @@ */ package net.sf.jsqlparser.statement.create; -import java.io.StringReader; +import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.io.StringReader; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserManager; import net.sf.jsqlparser.parser.CCJSqlParserUtil; @@ -20,14 +25,7 @@ import net.sf.jsqlparser.statement.create.view.CreateView; import net.sf.jsqlparser.statement.select.ParenthesedSelect; import net.sf.jsqlparser.statement.select.PlainSelect; -import static net.sf.jsqlparser.test.TestUtils.*; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - import org.assertj.core.api.ThrowableAssert.ThrowingCallable; -import static org.junit.jupiter.api.Assertions.assertTrue; - import org.junit.jupiter.api.Test; public class CreateViewTest { @@ -212,4 +210,33 @@ public void testCreateMaterializedViewIfNotExists() throws JSQLParserException { assertTrue(createView.isIfNotExists()); } + @Test + public void testCreateViewWithColumnComment() throws JSQLParserException { + String stmt = + "CREATE VIEW v14(c1 COMMENT 'comment1', c2 COMMENT 'comment2') AS SELECT c1, C2 FROM t1 WITH READ ONLY"; + assertSqlCanBeParsedAndDeparsed(stmt); + + String stmt2 = + "CREATE VIEW v14(c1 COMMENT 'comment1', c2) AS SELECT c1, C2 FROM t1 WITH READ ONLY"; + assertSqlCanBeParsedAndDeparsed(stmt2); + + String stmt3 = + "CREATE VIEW v14(c1, c2) COMMENT = 'view' AS SELECT c1, C2 FROM t1 WITH READ ONLY"; + assertSqlCanBeParsedAndDeparsed(stmt3); + } + + @Test + public void testCreateViewWithTableComment1() throws JSQLParserException { + String stmt = + "CREATE VIEW v14(c1 COMMENT 'comment1', c2 COMMENT 'comment2') COMMENT 'view' AS SELECT c1, C2 FROM t1 WITH READ ONLY"; + assertSqlCanBeParsedAndDeparsed(stmt); + } + + @Test + public void testCreateViewWithTableComment2() throws JSQLParserException { + String stmt = + "CREATE VIEW v14(c1 COMMENT 'comment1', c2 COMMENT 'comment2') COMMENT = 'view' AS SELECT c1, C2 FROM t1 WITH READ ONLY"; + assertSqlCanBeParsedAndDeparsed(stmt); + } + } diff --git a/src/test/java/net/sf/jsqlparser/statement/create/table/ColDataTypeTest.java b/src/test/java/net/sf/jsqlparser/statement/create/table/ColDataTypeTest.java new file mode 100644 index 000000000..bc2cb5c4b --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/statement/create/table/ColDataTypeTest.java @@ -0,0 +1,43 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2023 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement.create.table; + +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.test.TestUtils; +import org.junit.jupiter.api.Test; + +class ColDataTypeTest { + @Test + void testPublicType() throws JSQLParserException { + String sqlStr = "select 1::public.integer"; + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } + + @Test + void testIssue1879() throws JSQLParserException { + String sqlStr = "CREATE TABLE public.film (\n" + + " film_id integer DEFAULT nextval('public.film_film_id_seq'::regclass) NOT NULL,\n" + + + " title character varying(255) NOT NULL,\n" + + " description text,\n" + + " release_year public.year,\n" + + " language_id smallint NOT NULL,\n" + + " rental_duration smallint DEFAULT 3 NOT NULL,\n" + + " rental_rate numeric(4,2) DEFAULT 4.99 NOT NULL,\n" + + " length smallint,\n" + + " replacement_cost numeric(5,2) DEFAULT 19.99 NOT NULL,\n" + + " rating public.mpaa_rating DEFAULT 'G'::public.mpaa_rating,\n" + + " last_update timestamp without time zone DEFAULT now() NOT NULL,\n" + + " special_features text[],\n" + + " fulltext tsvector NOT NULL\n" + + ")"; + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } +} diff --git a/src/test/java/net/sf/jsqlparser/statement/merge/MergeTest.java b/src/test/java/net/sf/jsqlparser/statement/merge/MergeTest.java index 9a59f8aa1..edf0baa92 100644 --- a/src/test/java/net/sf/jsqlparser/statement/merge/MergeTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/merge/MergeTest.java @@ -173,11 +173,96 @@ public void testInsertMergeWhere() throws JSQLParserException { @Test public void testWith() throws JSQLParserException { - String statement = "" + "WITH a\n" + " AS (SELECT 1 id_instrument_ref)\n" + " , b\n" - + " AS (SELECT 1 id_instrument_ref)\n" + "MERGE INTO cfe.instrument_ref b\n" - + "using a\n" + "ON ( b.id_instrument_ref = a.id_instrument_ref )\n" - + "WHEN matched THEN\n" + " UPDATE SET b.id_instrument = 'a' "; - statement = "" + "WITH a\n" + " AS (SELECT 1 id_instrument_ref)\n" + "select * from a "; + String statement = "" + + "WITH a\n" + + " AS (SELECT 1 id_instrument_ref)\n" + + "select * from a "; assertSqlCanBeParsedAndDeparsed(statement, true); } + + @Test + public void testOutputClause() throws JSQLParserException { + String sqlStr = "" + + "WITH\n" + + " WMachine AS\n" + + " ( SELECT\n" + + " DISTINCT \n" + + " ProjCode,\n" + + " PlantCode,\n" + + " BuildingCode,\n" + + " FloorCode,\n" + + " Room\n" + + " FROM\n" + + " TAB_MachineLocation\n" + + " WHERE\n" + + " TRIM(Room) <> '' AND TRIM(Room) <> '-'\n" + + " ) \n" + + " MERGE INTO\n" + + " TAB_RoomLocation AS TRoom\n" + + " USING\n" + + " WMachine\n" + + " ON\n" + + " (\n" + + " TRoom.ProjCode = WMachine.ProjCode\n" + + " AND TRoom.PlantCode = WMachine.PlantCode\n" + + " AND TRoom.BuildingCode = WMachine.BuildingCode\n" + + " AND TRoom.FloorCode = WMachine.FloorCode\n" + + " AND TRoom.Room = WMachine.Room)\n" + + " WHEN NOT MATCHED /* BY TARGET */ THEN\n" + + " INSERT\n" + + " (\n" + + " ProjCode,\n" + + " PlantCode,\n" + + " BuildingCode,\n" + + " FloorCode,\n" + + " Room\n" + + " )\n" + + " VALUES\n" + + " (\n" + + " WMachine.ProjCode,\n" + + " WMachine.PlantCode,\n" + + " WMachine.BuildingCode,\n" + + " WMachine.FloorCode,\n" + + " WMachine.Room\n" + + " )\n" + + " OUTPUT GETDATE() AS TimeAction,\n" + + " $action as Action,\n" + + " INSERTED.ProjCode,\n" + + " INSERTED.PlantCode,\n" + + " INSERTED.BuildingCode,\n" + + " INSERTED.FloorCode,\n" + + " INSERTED.Room\n" + + " INTO\n" + + " TAB_MergeActions_RoomLocation"; + assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } + + @Test + public void testSnowflakeMergeStatementSimple() throws JSQLParserException { + String sql = "MERGE INTO target\n" + + " USING src ON target.k = src.k\n" + + " WHEN MATCHED THEN UPDATE SET target.v = src.v"; + + assertSqlCanBeParsedAndDeparsed(sql, true); + } + + @Test + public void testSnowflakeMergeStatementWithMatchedAndPredicate() throws JSQLParserException { + String sql = "MERGE INTO target\n" + + " USING src ON target.k = src.k\n" + + " WHEN MATCHED AND src.v = 11 THEN UPDATE SET target.v = src.v"; + + assertSqlCanBeParsedAndDeparsed(sql, true); + } + + @Test + void testSnowflakeMergeStatementWithNotMatchedAndPredicate() throws JSQLParserException { + String sql = + "MERGE INTO target USING (select k, max(v) as v from src group by k) AS b ON target.k = b.k\n" + + + " WHEN MATCHED THEN UPDATE SET target.v = b.v\n" + + " WHEN NOT MATCHED AND b.v != 11 THEN INSERT (k, v) VALUES (b.k, b.v)"; + + assertSqlCanBeParsedAndDeparsed(sql, true); + } } diff --git a/src/test/java/net/sf/jsqlparser/statement/select/ClickHouseTest.java b/src/test/java/net/sf/jsqlparser/statement/select/ClickHouseTest.java index 69cd90e6e..72b8508df 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/ClickHouseTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/ClickHouseTest.java @@ -10,8 +10,10 @@ package net.sf.jsqlparser.statement.select; import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; @@ -37,33 +39,24 @@ public void testFunctionWithAttributesIssue1742() throws JSQLParserException { } @Test - public void testSelectUsingFinal() throws JSQLParserException { - String sqlStr = "SELECT column FROM table_name AS tn FINAL"; - assertSqlCanBeParsedAndDeparsed(sqlStr, true); - - // check that FINAL is reserved keyword and won't be read as an Alias - sqlStr = "SELECT column FROM table_name FINAL"; - PlainSelect select = (PlainSelect) assertSqlCanBeParsedAndDeparsed(sqlStr, true); - - Assertions.assertTrue(select.isUsingFinal()); - Assertions.assertFalse(select.withUsingFinal(false).toString().contains("FINAL")); + public void testGlobalIn() throws JSQLParserException { + String sql = + "SELECT lo_linenumber,lo_orderkey from lo_linenumber where lo_linenumber global in (1,2,3)"; + assertSqlCanBeParsedAndDeparsed(sql, true); } @Test - public void testLimitBy() throws JSQLParserException { - String sqlStr = "SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id"; - assertSqlCanBeParsedAndDeparsed(sqlStr, true); - - sqlStr = "SELECT\n" - + " domainWithoutWWW(URL) AS domain,\n" - + " domainWithoutWWW(REFERRER_URL) AS referrer,\n" - + " device_type,\n" - + " count() cnt\n" - + "FROM hits\n" - + "GROUP BY domain, referrer, device_type\n" - + "ORDER BY cnt DESC\n" - + "LIMIT 5 BY domain, device_type\n" - + "LIMIT 100"; - assertSqlCanBeParsedAndDeparsed(sqlStr, true); + public void testGlobalKeywordIssue1883() throws JSQLParserException { + String sqlStr = "select a.* from a global join b on a.name = b.name "; + PlainSelect select = (PlainSelect) assertSqlCanBeParsedAndDeparsed(sqlStr, true); + Assertions.assertTrue(select.getJoins().get(0).isGlobal()); + + Assertions.assertThrows( + JSQLParserException.class, new Executable() { + @Override + public void execute() throws Throwable { + CCJSqlParserUtil.parse("select a.* from a global"); + } + }, "Fail when restricted keyword GLOBAL is used as an Alias."); } } diff --git a/src/test/java/net/sf/jsqlparser/statement/select/FetchTest.java b/src/test/java/net/sf/jsqlparser/statement/select/FetchTest.java index 8ccbd2bb8..0d97006ec 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/FetchTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/FetchTest.java @@ -32,4 +32,10 @@ void getExpression() throws JSQLParserException { Fetch fetch = plainSelect.getFetch(); Assertions.assertInstanceOf(ParenthesedSelect.class, fetch.getExpression()); } + + @Test + void testFetchWithoutExpressionIssue1859() throws JSQLParserException { + String sqlStr = "select 1 from test.dual fetch first row only"; + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } } diff --git a/src/test/java/net/sf/jsqlparser/statement/select/JoinHintTest.java b/src/test/java/net/sf/jsqlparser/statement/select/JoinHintTest.java new file mode 100644 index 000000000..9f7a63132 --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/statement/select/JoinHintTest.java @@ -0,0 +1,44 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2023 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement.select; + +import java.util.stream.Stream; +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.test.TestUtils; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +class JoinHintTest { + public static Stream sqlStrings() { + return Stream.of( + "SELECT p.Name, pr.ProductReviewID \n" + + "FROM Production.Product AS p \n" + + "LEFT OUTER HASH JOIN Production.ProductReview AS pr \n" + + "ON p.ProductID = pr.ProductID \n" + + "ORDER BY ProductReviewID DESC", + + "DELETE spqh \n" + + "FROM Sales.SalesPersonQuotaHistory AS spqh \n" + + " INNER LOOP JOIN Sales.SalesPerson AS sp \n" + + " ON spqh.SalesPersonID = sp.SalesPersonID \n" + + "WHERE sp.SalesYTD > 2500000.00", + + "SELECT poh.PurchaseOrderID, poh.OrderDate, pod.ProductID, pod.DueDate, poh.VendorID \n" + + "FROM Purchasing.PurchaseOrderHeader AS poh \n" + + "INNER MERGE JOIN Purchasing.PurchaseOrderDetail AS pod \n" + + " ON poh.PurchaseOrderID = pod.PurchaseOrderID"); + } + + @ParameterizedTest + @MethodSource("sqlStrings") + void testJoinHint(String sqlStr) throws JSQLParserException { + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } +} diff --git a/src/test/java/net/sf/jsqlparser/statement/select/NestedBracketsPerformanceTest.java b/src/test/java/net/sf/jsqlparser/statement/select/NestedBracketsPerformanceTest.java index 6a85d65d2..569b88873 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/NestedBracketsPerformanceTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/NestedBracketsPerformanceTest.java @@ -228,4 +228,131 @@ public void testIssue1103() throws JSQLParserException { + ",0),0),0),0),0),0),0),0)\n" + ",0),0),0),0),0),0),0),0)", true); } + + @Test + public void testDeepFunctionParameters() throws JSQLParserException { + String sqlStr = "SELECT a.*\n" + + " , To_Char( a.eingangsdat, 'MM.YY' ) AS eingmonat\n" + + " , ( SELECT Trim( b.atext )\n" + + " FROM masseinheiten x\n" + + " , a_lmt b\n" + + " WHERE x.a_text_id = b.a_text_id\n" + + " AND b.sprach_kz = sprache\n" + + " AND x.masseinh_id = a.masseinh_id ) AS reklamengesonst_bez\n" + + " , ( SELECT Trim( name ) || ' ' || Trim( vorname ) AS eingangerfasser_name\n" + + " FROM personal\n" + + " WHERE mandanten_id = m_personal\n" + + " AND personal_id = eingangerfasser ) AS eingangerfasser_name\n" + + " , Nvl( ( SELECT Max( change_date )\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id\n" + + " AND beschstatus_id = 9\n" + + " AND Nvl( inaktiv, 'F' ) != 'T' ), sysdate ) AS abschlussdatum\n" + + " , a.sachstand\n" + + " , a.bewertung\n" + + " , a.massnahmen\n" + + " , ( Decode( Nvl( ( SELECT Max( Trunc( change_date ) ) - Trunc( a.adate )\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id\n" + + " AND beschstatus_id = 9\n" + + " AND Nvl( inaktiv, 'F' ) != 'T' ), - 1 )\n" + + " , - 1, Trunc( sysdate ) - Trunc( a.adate ) - ( SELECT Count()\n" + + " FROM firmenkalender\n" + + " WHERE firma_id = firmen_id\n" + + " AND Nvl( b_verkauf, 'F' ) = 'T'\n" + + " AND kal_datum BETWEEN Trunc( a.adate )\n" + + " AND Trunc( sysdate ) )\n" + + " , Nvl( ( SELECT Max( Trunc( change_date ) ) - Trunc( a.adate )\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id\n" + + " AND beschstatus_id = 9\n" + + " AND Nvl( inaktiv, 'F' ) != 'T' ), - 1 )\n" + + " - ( SELECT Count()\n" + + " FROM firmenkalender\n" + + " WHERE firma_id = firmen_id\n" + + " AND Nvl( b_verkauf, 'F' ) = 'T'\n" + + " AND kal_datum BETWEEN Trunc( a.adate )\n" + + " AND ( SELECT Max( Trunc( change_date ) )\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id\n" + + " AND beschstatus_id = 9\n" + + " AND Nvl( inaktiv, 'F' ) != 'T' ) ) ) + 1 ) AS laufzeit\n" + + " , Nvl( ( SELECT grenzwert\n" + + " FROM beschfehler\n" + + " WHERE beschfehler_id = a.beschwkat_id ), 0 ) AS grenzwert\n" + + " , Nvl( ( SELECT warnwert\n" + + " FROM beschfehler\n" + + " WHERE beschfehler_id = a.beschwkat_id ), 0 ) AS warnwert\n" + + " , a.beschstatus_id AS pruef_status\n" + + " , ( CASE\n" + + " WHEN ( ( Decode( Nvl( ( SELECT Max( Trunc( change_date ) ) - Trunc( a.adate )\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id\n" + + " AND beschstatus_id = 9\n" + + " AND Nvl( inaktiv, 'F' ) != 'T' ), - 1 )\n" + + " , - 1, Trunc( sysdate ) - Trunc( a.adate ) - ( SELECT Count()\n" + + " FROM firmenkalender\n" + + " WHERE firma_id = firmen_id\n" + + " AND Nvl( b_verkauf, 'F' ) = 'T'\n" + + " AND kal_datum BETWEEN Trunc( a.adate )\n" + + " AND Trunc( sysdate ) )\n" + + " , Nvl( ( SELECT Max( Trunc( change_date ) ) - Trunc( a.adate )\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id\n" + + " AND beschstatus_id = 9\n" + + " AND Nvl( inaktiv, 'F' ) != 'T' ), - 1 )\n" + + " - ( SELECT Count()\n" + + " FROM firmenkalender\n" + + " WHERE firma_id = firmen_id\n" + + " AND Nvl( b_verkauf, 'F' ) = 'T'\n" + + " AND kal_datum BETWEEN Trunc( a.adate )\n" + + " AND ( SELECT Max( Trunc( change_date ) )\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id\n" + + " AND beschstatus_id = 9\n" + + " AND Nvl( inaktiv, 'F' ) != 'T' ) ) ) + 1 ) - Nvl( ( SELECT grenzwert\n" + + " FROM beschfehler\n" + + " WHERE beschfehler_id = a.beschwkat_id ), 0 ) ) < 0\n" + + " THEN 0\n" + + " ELSE ( ( Decode( Nvl( ( SELECT Max( Trunc( change_date ) ) - Trunc( a.adate )\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id\n" + + " AND beschstatus_id = 9\n" + + " AND Nvl( inaktiv, 'F' ) != 'T' ), - 1 )\n" + + " , - 1, Trunc( sysdate ) - Trunc( a.adate ) - ( SELECT Count()\n" + + " FROM firmenkalender\n" + + " WHERE firma_id = firmen_id\n" + + " AND Nvl( b_verkauf, 'F' ) = 'T'\n" + + " AND kal_datum BETWEEN Trunc( a.adate )\n" + + " AND Trunc( sysdate ) )\n" + + " , Nvl( ( SELECT Max( Trunc( change_date ) ) - Trunc( a.adate )\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id\n" + + " AND beschstatus_id = 9\n" + + " AND Nvl( inaktiv, 'F' ) != 'T' ), - 1 )\n" + + " - ( SELECT Count( * )\n" + + " FROM firmenkalender\n" + + " WHERE firma_id = firmen_id\n" + + " AND Nvl( b_verkauf, 'F' ) = 'T'\n" + + " AND kal_datum BETWEEN Trunc( a.adate )\n" + + " AND ( SELECT Max( Trunc( change_date ) )\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id\n" + + " AND beschstatus_id = 9\n" + + " AND Nvl( inaktiv, 'F' ) != 'T' ) ) ) + 1 ) - Nvl( ( SELECT grenzwert\n" + + " FROM beschfehler\n" + + " WHERE beschfehler_id = a.beschwkat_id ), 0 ) )\n" + + " END ) AS grenz_ueber\n" + + "FROM beschwerden a\n" + + "WHERE a.mandanten_id = m_beschwerde\n" + + " AND a.rec_status <> '9'\n" + + " AND EXISTS ( SELECT 1\n" + + " FROM besch_statusaenderung\n" + + " WHERE beschwerden_id = a.beschwerden_id )\n" + + " AND Nvl( ( SELECT grenzwert\n" + + " FROM beschfehler\n" + + " WHERE beschfehler_id = a.beschwkat_id ), 0 ) > 0\n"; + + assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } } diff --git a/src/test/java/net/sf/jsqlparser/statement/select/PostgresTest.java b/src/test/java/net/sf/jsqlparser/statement/select/PostgresTest.java index 921435026..56d36d854 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/PostgresTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/PostgresTest.java @@ -57,9 +57,9 @@ public void testJSonExpressionIssue1696() throws JSQLParserException { String sqlStr = "SELECT '{\"key\": \"value\"}'::json -> 'key' AS X"; PlainSelect plainSelect = (PlainSelect) assertSqlCanBeParsedAndDeparsed(sqlStr, true); SelectItem selectExpressionItem = - (SelectItem) plainSelect.getSelectItems().get(0); + plainSelect.getSelectItems().get(0); Assertions.assertEquals("'key'", - selectExpressionItem.getExpression(JsonExpression.class).getIdents().get(0)); + selectExpressionItem.getExpression(JsonExpression.class).getIdent(0).getKey()); } @Test @@ -95,4 +95,10 @@ void testPostgresQuotingIssue1335() throws JSQLParserException { "\"column\"\"with\"\"quotes\"", selectItems.get(0).getExpression(Column.class).getColumnName()); } + + @Test + void testNextValueIssue1863() throws JSQLParserException { + String sqlStr = "SELECT nextval('client_id_seq')"; + assertSqlCanBeParsedAndDeparsed(sqlStr); + } } diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java index afba71f3a..527313bfe 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java @@ -9,6 +9,29 @@ */ package net.sf.jsqlparser.statement.select; +import static net.sf.jsqlparser.test.TestUtils.assertDeparse; +import static net.sf.jsqlparser.test.TestUtils.assertExpressionCanBeDeparsedAs; +import static net.sf.jsqlparser.test.TestUtils.assertExpressionCanBeParsedAndDeparsed; +import static net.sf.jsqlparser.test.TestUtils.assertOracleHintExists; +import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; +import static net.sf.jsqlparser.test.TestUtils.assertStatementCanBeDeparsedAs; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Alias; import net.sf.jsqlparser.expression.AllValue; @@ -56,29 +79,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import java.io.IOException; -import java.io.StringReader; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; - -import static net.sf.jsqlparser.test.TestUtils.assertDeparse; -import static net.sf.jsqlparser.test.TestUtils.assertExpressionCanBeDeparsedAs; -import static net.sf.jsqlparser.test.TestUtils.assertExpressionCanBeParsedAndDeparsed; -import static net.sf.jsqlparser.test.TestUtils.assertOracleHintExists; -import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; -import static net.sf.jsqlparser.test.TestUtils.assertStatementCanBeDeparsedAs; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - @Execution(ExecutionMode.CONCURRENT) public class SelectTest { @@ -578,14 +578,17 @@ public void testLimitSqlServer1() throws JSQLParserException { Select select = (Select) parserManager.parse(new StringReader(statement)); assertNotNull(select.getOffset()); + assertEquals("3", + select.getOffset().getOffset().toString()); assertEquals("ROWS", select.getOffset().getOffsetParam()); + assertNotNull(select.getFetch()); - assertEquals("ROWS", select.getFetch().getFetchParam()); assertFalse(select.getFetch().isFetchParamFirst()); - assertNull(select.getFetch().getFetchJdbcParameter()); - assertEquals("3", - select.getOffset().getOffset().toString()); - assertEquals(5, select.getFetch().getRowCount()); + assertEquals("5", select.getFetch().getExpression().toString()); + org.assertj.core.api.Assertions + .assertThat(select.getFetch().getFetchParameters()) + .containsExactly("ROWS", "ONLY"); + assertStatementCanBeDeparsedAs(select, statement); } @@ -598,13 +601,15 @@ public void testLimitSqlServer2() throws JSQLParserException { Select select = (Select) parserManager.parse(new StringReader(statement)); assertNotNull(select.getOffset()); - assertNotNull(select.getFetch()); assertEquals("ROW", select.getOffset().getOffsetParam()); - assertEquals("ROW", select.getFetch().getFetchParam()); + + assertNotNull(select.getFetch()); assertTrue(select.getFetch().isFetchParamFirst()); - assertEquals(new LongValue(3), - select.getOffset().getOffset()); - assertEquals(5, select.getFetch().getRowCount()); + assertEquals("5", select.getFetch().getExpression().toString()); + org.assertj.core.api.Assertions + .assertThat(select.getFetch().getFetchParameters()) + .containsExactly("ROW", "ONLY"); + assertStatementCanBeDeparsedAs(select, statement); } @@ -634,9 +639,11 @@ public void testLimitSqlServer4() throws JSQLParserException { assertNull(select.getOffset()); assertNotNull(select.getFetch()); - assertEquals("ROWS", select.getFetch().getFetchParam()); assertFalse(select.getFetch().isFetchParamFirst()); - assertEquals(5, select.getFetch().getRowCount()); + assertEquals("5", select.getFetch().getExpression().toString()); + org.assertj.core.api.Assertions + .assertThat(select.getFetch().getFetchParameters()) + .containsExactly("ROWS", "ONLY"); assertStatementCanBeDeparsedAs(select, statement); } @@ -650,12 +657,14 @@ public void testLimitSqlServerJdbcParameters() throws JSQLParserException { assertNotNull(select.getOffset()); assertEquals("ROWS", select.getOffset().getOffsetParam()); assertNotNull(select.getFetch()); - assertEquals("ROWS", select.getFetch().getFetchParam()); assertFalse(select.getFetch().isFetchParamFirst()); + assertEquals("?", select.getFetch().getExpression().toString()); + org.assertj.core.api.Assertions + .assertThat(select.getFetch().getFetchParameters()) + .containsExactly("ROWS", "ONLY"); assertEquals("?", select.getOffset().getOffset().toString()); - assertEquals("?", select.getFetch().getFetchJdbcParameter() - .toString()); + assertStatementCanBeDeparsedAs(select, statement); } @@ -1202,7 +1211,7 @@ public void testFunctions() throws JSQLParserException { .getExpression(); assertEquals("MAX", fun.getName()); assertEquals("b", - ((Column) fun.getParameters().getExpressions().get(1)).getFullyQualifiedName()); + ((Column) fun.getParameters().get(1)).getFullyQualifiedName()); assertTrue(((Function) (plainSelect.getSelectItems().get(1)) .getExpression()).getParameters().getExpressions().get(0) instanceof AllColumns); assertStatementCanBeDeparsedAs(select, statement); @@ -1469,24 +1478,21 @@ public void testCase() throws JSQLParserException { statement = "SELECT a FROM tab1 WHERE CASE b WHEN 1 THEN 2 + 3 ELSE 4 END > 34"; assertSqlCanBeParsedAndDeparsed(statement); - statement = - "SELECT a, (CASE " + "WHEN (CASE a WHEN 1 THEN 10 ELSE 20 END) > 15 THEN 'BBB' " + // "WHEN - // (SELECT - // c - // FROM - // tab2 - // WHERE - // d - // = - // 2) - // = - // 3 - // THEN - // 'AAA' - // " - // + - "END) FROM tab1"; - assertSqlCanBeParsedAndDeparsed(statement); + statement = "SELECT a\n" + + " , ( CASE\n" + + " WHEN ( CASE\n" + + " WHEN 1\n" + + " THEN 10\n" + + " ELSE 20\n" + + " END ) > 15\n" + + " THEN 'BBB'\n" + + " WHEN ( SELECT c\n" + + " FROM tab2\n" + + " WHERE d = 2 ) = 3\n" + + " THEN 'AAA'\n" + + " END )\n" + + "FROM tab1\n"; + assertSqlCanBeParsedAndDeparsed(statement, true); } @Test @@ -2243,6 +2249,18 @@ public void testIsNotFalse() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed(statement); } + @Test + public void testTSQLJoin() throws JSQLParserException { + String stmt = "SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.a *= tabelle2.b"; + assertSqlCanBeParsedAndDeparsed(stmt); + } + + @Test + public void testTSQLJoin2() throws JSQLParserException { + String stmt = "SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.a =* tabelle2.b"; + assertSqlCanBeParsedAndDeparsed(stmt); + } + @Test public void testOracleJoin() throws JSQLParserException { String stmt = "SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.a = tabelle2.b(+)"; @@ -2409,12 +2427,6 @@ public void testExtractFrom4() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed(stmt); } - // @Test - // public void testExtractFromIssue673() throws JSQLParserException { - // String stmt = "select EXTRACT(DAY FROM (SYSDATE - to_date('20180101', 'YYYYMMDD' ) ) DAY TO - // SECOND) from dual"; - // assertSqlCanBeParsedAndDeparsed(stmt); - // } @Test public void testProblemFunction() throws JSQLParserException { String stmt = "SELECT test() FROM testtable"; @@ -4195,7 +4207,16 @@ public void testFuncConditionParameter2() throws JSQLParserException { @Test public void testFuncConditionParameter3() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed( - "SELECT CAST((MAX(CAST(IIF(isnumeric(license_no) = 1, license_no, 0) AS INT)) + 2) AS varchar) FROM lcps.t_license WHERE profession_id = 60 and license_type = 100 and YEAR(issue_date) % 2 = case when YEAR(issue_date) % 2 = 0 then 0 else 1 end and ISNUMERIC(license_no) = 1", + "SELECT cast( ( Max( cast( Iif( Isnumeric( license_no ) = 1, license_no, 0 ) AS INT ) ) + 2 ) AS VARCHAR )\n" + + "FROM lcps.t_license\n" + + "WHERE profession_id = 60\n" + + " AND license_type = 100\n" + + " AND Year( issue_date ) % 2 = CASE\n" + + " WHEN Year( issue_date ) % 2 = 0\n" + + " THEN 0\n" + + " ELSE 1\n" + + " END\n" + + " AND Isnumeric( license_no ) = 1", true); } @@ -4591,6 +4612,20 @@ public void testMultiColumnAliasIssue849_2() throws JSQLParserException { "SELECT * FROM crosstab('select rowid, attribute, value from ct where attribute = ''att2'' or attribute = ''att3'' order by 1,2') AS ct(row_name text, category_1 text, category_2 text, category_3 text)"); } + @Test + public void testTableStatementIssue1836() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed( + "TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10"); + assertSqlCanBeParsedAndDeparsed( + "TABLE columns ORDER BY column_name LIMIT 10"); + assertSqlCanBeParsedAndDeparsed( + "TABLE columns ORDER BY column_name"); + assertSqlCanBeParsedAndDeparsed( + "TABLE columns LIMIT 10 OFFSET 10"); + assertSqlCanBeParsedAndDeparsed( + "TABLE columns LIMIT 10"); + } + @Test public void testLimitClauseDroppedIssue845() throws JSQLParserException { assertEquals("SELECT * FROM employee ORDER BY emp_id LIMIT 10 OFFSET 2", CCJSqlParserUtil @@ -4767,6 +4802,27 @@ public void testCurrentIssue940() throws JSQLParserException { "SELECT date(current) AS test_date FROM systables WHERE tabid = 1"); } + @Test + public void testIssue1878() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("SELECT * FROM MY_TABLE1 FOR SHARE"); + // PostgreSQL ONLY + assertSqlCanBeParsedAndDeparsed("SELECT * FROM MY_TABLE1 FOR NO KEY UPDATE"); + assertSqlCanBeParsedAndDeparsed("SELECT * FROM MY_TABLE1 FOR KEY SHARE"); + } + + @Test + public void testIssue1878ViaJava() throws JSQLParserException { + String expectedSQLStr = "SELECT * FROM MY_TABLE1 FOR SHARE"; + + // Step 1: generate the Java Object Hierarchy for + Table table = new Table().withName("MY_TABLE1"); + + PlainSelect select = new PlainSelect().addSelectItem(new AllColumns()) + .withFromItem(table).withForMode(ForMode.KEY_SHARE).withForMode(ForMode.SHARE); + + Assertions.assertEquals(expectedSQLStr, select.toString()); + } + @Test public void testKeyWordView() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed( @@ -5527,7 +5583,7 @@ public void testSelectStatementWithForUpdateAndSkipLockedTokens() throws JSQLPar Select select = (Select) CCJSqlParserUtil.parse(sql); PlainSelect plainSelect = (PlainSelect) select; - assertTrue(plainSelect.isForUpdate()); + assertSame(plainSelect.getForMode(), ForMode.UPDATE); assertTrue(plainSelect.isSkipLocked()); } @@ -5539,7 +5595,7 @@ public void testSelectStatementWithForUpdateButWithoutSkipLockedTokens() Select select = (Select) CCJSqlParserUtil.parse(sql); PlainSelect plainSelect = (PlainSelect) select; - assertTrue(plainSelect.isForUpdate()); + assertSame(plainSelect.getForMode(), ForMode.UPDATE); assertFalse(plainSelect.isSkipLocked()); } @@ -5551,7 +5607,7 @@ public void testSelectStatementWithoutForUpdateAndSkipLockedTokens() Select select = (Select) CCJSqlParserUtil.parse(sql); PlainSelect plainSelect = (PlainSelect) select; - assertFalse(plainSelect.isForUpdate()); + assertNull(plainSelect.getForMode()); assertFalse(plainSelect.isSkipLocked()); } @@ -5739,4 +5795,15 @@ void testBackSlashQuotationIssue1812() throws JSQLParserException { sqlStr, parser -> parser .withBackslashEscapeCharacter(true)); } + + @Test + public void testIssue1907() throws JSQLParserException { + String stmt = "SELECT MAX(a, b, c), COUNT(*), D FROM tab1 GROUP BY D WITH ROLLUP"; + assertSqlCanBeParsedAndDeparsed(stmt); + + // since mysql 8.0.12 + String stmt2 = + "SELECT * FROM (SELECT year, person, SUM(amount) FROM rentals GROUP BY year, person) t1 ORDER BY year DESC WITH ROLLUP"; + assertSqlCanBeParsedAndDeparsed(stmt2); + } } diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SpecialOracleTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SpecialOracleTest.java index 6d2b4a1a8..d0bbed775 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/SpecialOracleTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/SpecialOracleTest.java @@ -9,11 +9,18 @@ */ package net.sf.jsqlparser.statement.select; +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import org.apache.commons.io.FileUtils; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; + import java.io.File; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.IOException; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.util.Arrays; import java.util.Date; @@ -21,22 +28,17 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import net.sf.jsqlparser.JSQLParserException; -import net.sf.jsqlparser.parser.CCJSqlParserUtil; + import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; -import org.apache.commons.io.FileUtils; -import org.assertj.core.api.Assertions; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; -import org.opentest4j.AssertionFailedError; /** - * Tries to parse and deparse all statments in net.sf.jsqlparser.test.oracle-tests. - * + * Tries to parse and de-parse all statements in net.sf.jsqlparser.test.oracle-tests. + *

    * As a matter of fact there are a lot of files that can still not processed. Here a step by step * improvement is the way to go. - * + *

    * The test ensures, that the successful parsed file count does not decrease. * * @author toben @@ -97,7 +99,8 @@ public class SpecialOracleTest { "join21.sql", "keywordasidentifier01.sql", "keywordasidentifier02.sql", "keywordasidentifier03.sql", "keywordasidentifier04.sql", "keywordasidentifier05.sql", "lexer02.sql", "lexer03.sql", "lexer04.sql", "lexer05.sql", "like01.sql", "merge01.sql", - "merge02.sql", "order_by01.sql", "order_by02.sql", "order_by03.sql", "order_by04.sql", + "merge02.sql", "merge03.sql", "merge04.sql", "order_by01.sql", "order_by02.sql", + "order_by03.sql", "order_by04.sql", "order_by05.sql", "order_by06.sql", "pivot01.sql", "pivot02.sql", "pivot03.sql", "pivot04.sql", "pivot05.sql", "pivot06.sql", "pivot07.sql", "pivot07_Parenthesis.sql", "pivot08.sql", "pivot09.sql", "pivot11.sql", "pivot12.sql", "query_factoring01.sql", @@ -118,10 +121,11 @@ public void testAllSqlsParseDeparse() throws IOException { boolean foundUnexpectedFailures = false; + assert sqlTestFiles != null; for (File file : sqlTestFiles) { if (file.isFile()) { count++; - String sql = FileUtils.readFileToString(file, Charset.forName("UTF-8")); + String sql = FileUtils.readFileToString(file, StandardCharsets.UTF_8); try { assertSqlCanBeParsedAndDeparsed(sql, true); success++; @@ -187,9 +191,10 @@ public boolean accept(File dir, String name) { } }); + assert sqlTestFiles != null; for (File file : sqlTestFiles) { if (file.isFile()) { - String sql = FileUtils.readFileToString(file, Charset.forName("UTF-8")); + String sql = FileUtils.readFileToString(file, StandardCharsets.UTF_8); assertSqlCanBeParsedAndDeparsed(sql, true); } } @@ -197,7 +202,7 @@ public boolean accept(File dir, String name) { public void recordSuccessOnSourceFile(File file) throws IOException { File sourceFile = new File(SQL_SOURCE_DIR, file.getName()); - String sourceSql = FileUtils.readFileToString(sourceFile, Charset.forName("UTF-8")); + String sourceSql = FileUtils.readFileToString(sourceFile, StandardCharsets.UTF_8); if (!sourceSql.contains("@SUCCESSFULLY_PARSED_AND_DEPARSED")) { LOG.log(Level.INFO, "NEW SUCCESS: {0}", file.getName()); if (sourceFile.exists() && sourceFile.canWrite()) { @@ -219,10 +224,10 @@ public void recordSuccessOnSourceFile(File file) throws IOException { public void recordFailureOnSourceFile(File file, String message) throws IOException { File sourceFile = new File(SQL_SOURCE_DIR, file.getName()); - String sourceSql = FileUtils.readFileToString(sourceFile, Charset.forName("UTF-8")); + String sourceSql = FileUtils.readFileToString(sourceFile, StandardCharsets.UTF_8); if (!sourceSql.contains("@FAILURE: " + message) && sourceFile.canWrite()) { try (FileWriter writer = new FileWriter(sourceFile, true)) { - writer.append("\n--@FAILURE: " + message + " recorded first on ") + writer.append("\n--@FAILURE: ").append(message).append(" recorded first on ") .append(DateFormat.getDateTimeInstance().format(new Date())); } } @@ -233,8 +238,9 @@ public void testAllSqlsOnlyParse() throws IOException { File[] sqlTestFiles = new File(SQLS_DIR, "only-parse-test").listFiles(); List regressionFiles = new LinkedList<>(); + assert sqlTestFiles != null; for (File file : sqlTestFiles) { - String sql = FileUtils.readFileToString(file, Charset.forName("UTF-8")); + String sql = FileUtils.readFileToString(file, StandardCharsets.UTF_8); try { CCJSqlParserUtil.parse(sql); LOG.log(Level.FINE, "EXPECTED SUCCESS: {0}", file.getName()); diff --git a/src/test/java/net/sf/jsqlparser/statement/update/UpdateTest.java b/src/test/java/net/sf/jsqlparser/statement/update/UpdateTest.java index bfebcdf37..342d1eea6 100644 --- a/src/test/java/net/sf/jsqlparser/statement/update/UpdateTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/update/UpdateTest.java @@ -18,12 +18,15 @@ import net.sf.jsqlparser.parser.CCJSqlParserManager; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.test.TestUtils; import org.junit.jupiter.api.Test; import java.io.StringReader; import static net.sf.jsqlparser.test.TestUtils.assertOracleHintExists; import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; +import static net.sf.jsqlparser.test.TestUtils.assertUpdateMysqlHintExists; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -208,6 +211,13 @@ public void testOracleHint() throws JSQLParserException { // Where o >= 3", true, "SOMEHINT"); } + @Test + public void testMysqlHint() throws JSQLParserException { + assertUpdateMysqlHintExists( + "UPDATE demo FORCE INDEX (idx_demo) SET col1 = NULL WHERE col2 = 1", true, "FORCE", + "INDEX", "idx_demo"); + } + @Test public void testWith() throws JSQLParserException { String statement = "" @@ -354,4 +364,20 @@ void testArrayColumnsIssue1083() throws JSQLParserException { sqlStr = "update utilisateur set listes[0:3] = (1,2,3,4)"; assertSqlCanBeParsedAndDeparsed(sqlStr, true); } + + @Test + void testIssue1910() throws JSQLParserException { + Update update = new Update(); + update.setTable(new Table("sys_dept")); + + UpdateSet updateSet = new UpdateSet(new Column("deleted"), new LongValue(1L)); + update.addUpdateSet(updateSet); + + TestUtils.assertStatementCanBeDeparsedAs(update, "UPDATE sys_dept SET deleted = 1", true); + + updateSet.add(new Column("created"), new LongValue(2L)); + + TestUtils.assertStatementCanBeDeparsedAs(update, + "UPDATE sys_dept SET (deleted, created) = (1,2)", true); + } } diff --git a/src/test/java/net/sf/jsqlparser/test/MemoryLeakVerifier.java b/src/test/java/net/sf/jsqlparser/test/MemoryLeakVerifier.java index 5784e5d95..112b6896d 100644 --- a/src/test/java/net/sf/jsqlparser/test/MemoryLeakVerifier.java +++ b/src/test/java/net/sf/jsqlparser/test/MemoryLeakVerifier.java @@ -101,7 +101,7 @@ private static void assertGarbageCollected(WeakReference ref, int maxIte for (int i = 0; i < maxIterations; i++) { runtime.runFinalization(); runtime.gc(); - if (ref.get() == null) { + if (ref == null || ref.get() == null) { break; } diff --git a/src/test/java/net/sf/jsqlparser/test/TestUtils.java b/src/test/java/net/sf/jsqlparser/test/TestUtils.java index 1554026ac..9ee16ae69 100644 --- a/src/test/java/net/sf/jsqlparser/test/TestUtils.java +++ b/src/test/java/net/sf/jsqlparser/test/TestUtils.java @@ -24,6 +24,7 @@ import java.util.stream.Stream; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.MySQLIndexHint; import net.sf.jsqlparser.expression.OracleHint; import net.sf.jsqlparser.parser.CCJSqlParser; import net.sf.jsqlparser.parser.CCJSqlParserUtil; @@ -410,4 +411,20 @@ public static void assertOracleHintExists(String sql, boolean assertDeparser, St assertEquals(hints[0], hint.getValue()); } } + + public static void assertUpdateMysqlHintExists(String sql, boolean assertDeparser, + String action, String qualifier, String... indexNames) + throws JSQLParserException { + if (assertDeparser) { + assertSqlCanBeParsedAndDeparsed(sql, true); + } + Statement statement = CCJSqlParserUtil.parse(sql); + assertInstanceOf(Update.class, statement); + Update updateStmt = (Update) statement; + final MySQLIndexHint indexHint = updateStmt.getTable().getIndexHint(); + assertNotNull(indexHint); + assertEquals(indexHint.getAction(), action); + assertEquals(indexHint.getIndexQualifier(), qualifier); + assertArrayEquals(indexHint.getIndexNames().toArray(), indexNames); + } } diff --git a/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java b/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java index 7d122df53..2f9566088 100644 --- a/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java +++ b/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java @@ -9,7 +9,17 @@ */ package net.sf.jsqlparser.util; -import jdk.nashorn.internal.ir.annotations.Ignore; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.util.List; +import java.util.Set; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.OracleHint; import net.sf.jsqlparser.parser.CCJSqlParserManager; @@ -23,35 +33,24 @@ import net.sf.jsqlparser.statement.simpleparsing.CCJSqlParserManagerTest; import net.sf.jsqlparser.test.TestException; import net.sf.jsqlparser.test.TestUtils; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.util.List; -import java.util.Set; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - public class TablesNamesFinderTest { private static final CCJSqlParserManager PARSER_MANAGER = new CCJSqlParserManager(); - @Ignore + @Disabled public void testRUBiSTableList() throws Exception { runTestOnResource("/RUBiS-select-requests.txt"); } - @Ignore + @Disabled public void testMoreComplexExamples() throws Exception { runTestOnResource("complex-select-requests.txt"); } - @Ignore + @Disabled public void testComplexMergeExamples() throws Exception { runTestOnResource("complex-merge-requests.txt"); } @@ -490,10 +489,37 @@ public void testConnectedByRootOperator() throws JSQLParserException { void testJoinSubSelect() throws JSQLParserException { String sqlStr = "select * from A left join B on A.id=B.id and A.age = (select age from C)"; Set tableNames = TablesNamesFinder.findTables(sqlStr); - assertThat( tableNames ).containsExactlyInAnyOrder("A", "B", "C"); + assertThat(tableNames).containsExactlyInAnyOrder("A", "B", "C"); String exprStr = "A.id=B.id and A.age = (select age from C)"; tableNames = TablesNamesFinder.findTablesInExpression(exprStr); - assertThat( tableNames ).containsExactlyInAnyOrder("A", "B", "C"); + assertThat(tableNames).containsExactlyInAnyOrder("A", "B", "C"); + } + + @Test + void testRefreshMaterializedView() throws JSQLParserException { + String sqlStr1 = "REFRESH MATERIALIZED VIEW CONCURRENTLY my_view WITH DATA"; + Set tableNames1 = TablesNamesFinder.findTables(sqlStr1); + assertThat(tableNames1).containsExactlyInAnyOrder("my_view"); + + String sqlStr2 = "REFRESH MATERIALIZED VIEW CONCURRENTLY my_view"; + Set tableNames2 = TablesNamesFinder.findTables(sqlStr2); + assertThat(tableNames2).containsExactlyInAnyOrder("my_view"); + + String sqlStr3 = "REFRESH MATERIALIZED VIEW my_view"; + Set tableNames3 = TablesNamesFinder.findTables(sqlStr3); + assertThat(tableNames3).containsExactlyInAnyOrder("my_view"); + + String sqlStr4 = "REFRESH MATERIALIZED VIEW my_view WITH DATA"; + Set tableNames4 = TablesNamesFinder.findTables(sqlStr4); + assertThat(tableNames4).containsExactlyInAnyOrder("my_view"); + + String sqlStr5 = "REFRESH MATERIALIZED VIEW my_view WITH NO DATA"; + Set tableNames5 = TablesNamesFinder.findTables(sqlStr5); + assertThat(tableNames5).containsExactlyInAnyOrder("my_view"); + + String sqlStr6 = "REFRESH MATERIALIZED VIEW CONCURRENTLY my_view WITH NO DATA"; + Set tableNames6 = TablesNamesFinder.findTables(sqlStr6); + assertThat(tableNames6).isEmpty(); } } diff --git a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java index e0f2d0b97..4248ef494 100644 --- a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java +++ b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java @@ -9,6 +9,13 @@ */ package net.sf.jsqlparser.util.deparser; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.LongValue; @@ -26,6 +33,7 @@ import net.sf.jsqlparser.statement.select.ParenthesedSelect; import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.SelectVisitor; +import net.sf.jsqlparser.statement.select.TableStatement; import net.sf.jsqlparser.statement.select.WithItem; import net.sf.jsqlparser.statement.update.Update; import net.sf.jsqlparser.statement.update.UpdateSet; @@ -37,14 +45,6 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; - @ExtendWith(MockitoExtension.class) public class StatementDeParserTest { @@ -56,8 +56,12 @@ public class StatementDeParserTest { private StatementDeParser statementDeParser; + private TableStatementDeParser tableStatementDeParser; + @BeforeEach public void setUp() { + tableStatementDeParser = + new TableStatementDeParser(expressionDeParser, new StringBuilder()); statementDeParser = new StatementDeParser(expressionDeParser, selectDeParser, new StringBuilder()); } @@ -326,6 +330,13 @@ public void testIssue1500AllColumns() throws JSQLParserException { selectBody.accept(new SelectDeParser()); } + @Test + public void testIssue1836() throws JSQLParserException { + String sqlStr = "TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10;"; + TableStatement tableStatement = (TableStatement) CCJSqlParserUtil.parse(sqlStr); + tableStatement.accept(tableStatementDeParser); + } + @Test public void testIssue1500AllTableColumns() throws JSQLParserException { String sqlStr = "select count(a.*) from some_table a"; diff --git a/src/test/java/net/sf/jsqlparser/util/validation/validator/CreateViewValidatorTest.java b/src/test/java/net/sf/jsqlparser/util/validation/validator/CreateViewValidatorTest.java index 92d4cd294..4c94bd041 100644 --- a/src/test/java/net/sf/jsqlparser/util/validation/validator/CreateViewValidatorTest.java +++ b/src/test/java/net/sf/jsqlparser/util/validation/validator/CreateViewValidatorTest.java @@ -37,18 +37,21 @@ public void testValidateCreateViewNotAllowed() throws JSQLParserException { @Test public void testValidateCreateViewMaterialized() throws JSQLParserException { - validateNoErrors("CREATE MATERIALIZED VIEW myview AS SELECT * FROM mytab", 1, DatabaseType.ORACLE); + validateNoErrors("CREATE MATERIALIZED VIEW myview AS SELECT * FROM mytab", 1, + DatabaseType.ORACLE); } @Test public void testValidateCreateOrReplaceView() throws JSQLParserException { - validateNoErrors("CREATE OR REPLACE VIEW myview AS SELECT * FROM mytab", 1, DatabaseType.ORACLE, + validateNoErrors("CREATE OR REPLACE VIEW myview AS SELECT * FROM mytab", 1, + DatabaseType.ORACLE, DatabaseType.POSTGRESQL, DatabaseType.MYSQL, DatabaseType.MARIADB, DatabaseType.H2); } @Test public void testValidateCreateForceView() throws JSQLParserException { - validateNoErrors("CREATE FORCE VIEW myview AS SELECT * FROM mytab", 1, DatabaseType.ORACLE, DatabaseType.H2); + validateNoErrors("CREATE FORCE VIEW myview AS SELECT * FROM mytab", 1, DatabaseType.ORACLE, + DatabaseType.H2); } @Test @@ -66,4 +69,12 @@ public void testValidateCreateViewWith() throws JSQLParserException { validateNoErrors(sql, 1, DatabaseType.DATABASES); } } + + @Test + public void testValidateCreateViewWithComment() throws JSQLParserException { + validateNoErrors( + "CREATE VIEW v14(c1 COMMENT 'comment1', c2 COMMENT 'comment2') COMMENT = 'view' AS SELECT c1, C2 FROM t1 WITH READ ONLY", + 1, + DatabaseType.MYSQL, DatabaseType.MARIADB); + } } diff --git a/src/test/java/net/sf/jsqlparser/util/validation/validator/RefreshMaterializedViewStatementValidatorTest.java b/src/test/java/net/sf/jsqlparser/util/validation/validator/RefreshMaterializedViewStatementValidatorTest.java new file mode 100644 index 000000000..1444c2961 --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/util/validation/validator/RefreshMaterializedViewStatementValidatorTest.java @@ -0,0 +1,66 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2020 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.util.validation.validator; + +import java.util.Arrays; +import net.sf.jsqlparser.parser.feature.Feature; +import net.sf.jsqlparser.util.validation.ValidationTestAsserts; +import net.sf.jsqlparser.util.validation.feature.DatabaseType; +import net.sf.jsqlparser.util.validation.feature.FeaturesAllowed; +import org.junit.jupiter.api.Test; + +/** + * @author jxnu-liguobin + */ + +public class RefreshMaterializedViewStatementValidatorTest extends ValidationTestAsserts { + + @Test + public void testValidationRefresh() throws Exception { + for (String sql : Arrays.asList("REFRESH MATERIALIZED VIEW my_view")) { + validateNoErrors(sql, 1, DatabaseType.POSTGRESQL); + } + } + + @Test + public void testValidationRefreshWithData() throws Exception { + for (String sql : Arrays + .asList("REFRESH MATERIALIZED VIEW CONCURRENTLY my_view WITH DATA")) { + validateNoErrors(sql, 1, DatabaseType.POSTGRESQL); + } + + for (String sql : Arrays.asList("REFRESH MATERIALIZED VIEW my_view WITH DATA")) { + validateNoErrors(sql, 1, DatabaseType.POSTGRESQL); + } + } + + @Test + public void testValidationRefreshWithConcurrently() throws Exception { + for (String sql : Arrays.asList("REFRESH MATERIALIZED VIEW CONCURRENTLY my_view")) { + validateNoErrors(sql, 1, DatabaseType.POSTGRESQL); + } + } + + + @Test + public void testValidationRefreshNotAllowed() throws Exception { + for (String sql : Arrays.asList("REFRESH MATERIALIZED VIEW my_view")) { + validateNotAllowed(sql, 1, 1, FeaturesAllowed.SELECT, + Feature.refreshMaterializedView); + } + + for (String sql : Arrays + .asList("REFRESH MATERIALIZED VIEW CONCURRENTLY my_view WITH DATA")) { + validateNotAllowed(sql, 1, 1, FeaturesAllowed.SELECT, + Feature.refreshMaterializedView, Feature.refreshMaterializedWithDataView, + Feature.refreshMaterializedWithNoDataView); + } + } +} diff --git a/src/test/java/net/sf/jsqlparser/util/validation/validator/SelectValidatorTest.java b/src/test/java/net/sf/jsqlparser/util/validation/validator/SelectValidatorTest.java index a22b34156..52b7a5396 100644 --- a/src/test/java/net/sf/jsqlparser/util/validation/validator/SelectValidatorTest.java +++ b/src/test/java/net/sf/jsqlparser/util/validation/validator/SelectValidatorTest.java @@ -68,6 +68,25 @@ public void testValidationForUpdateWaitWithTimeout() throws JSQLParserException validateNoErrors(sql, 1, DatabaseType.ORACLE, DatabaseType.MARIADB); } + @Test + public void testValidationForShare() throws JSQLParserException { + String sql = "SELECT * FROM mytable FOR SHARE"; + validateNoErrors(sql, 1, DatabaseType.MYSQL, DatabaseType.POSTGRESQL); + } + + @Test + public void testValidationForPostgresShare() throws JSQLParserException { + String sql = "SELECT * FROM mytable FOR KEY SHARE"; + validateNoErrors(sql, 1, DatabaseType.POSTGRESQL); + + String sql2 = "SELECT * FROM mytable FOR NO KEY UPDATE"; + validateNoErrors(sql2, 1, DatabaseType.POSTGRESQL); + + // Not familiar with oracle, please modify if supported. + validateNotSupported(sql2, 1, 1, DatabaseType.ORACLE, + Feature.selectForNoKeyUpdate); + } + @Test public void testValidationForUpdateNoWait() throws JSQLParserException { String sql = "SELECT * FROM mytable FOR UPDATE NOWAIT"; @@ -83,7 +102,8 @@ public void testValidationJoinOuterSimple() throws JSQLParserException { @Test public void testValidationJoin() throws JSQLParserException { - for (String sql : Arrays.asList("SELECT t1.col, t2.col, t1.id FROM tab1 t1, tab2 t2 WHERE t1.id = t2.id", + for (String sql : Arrays.asList( + "SELECT t1.col, t2.col, t1.id FROM tab1 t1, tab2 t2 WHERE t1.id = t2.id", "SELECT t1.col, t2.col, t1.id FROM tab1 t1 JOIN tab2 t2 ON t1.id = t2.id", "SELECT t1.col, t2.col, t1.id FROM tab1 t1 INNER JOIN tab2 t2 ON t1.id = t2.id")) { validateNoErrors(sql, 1, DatabaseType.DATABASES); @@ -92,7 +112,8 @@ public void testValidationJoin() throws JSQLParserException { @Test public void testOracleHierarchicalQuery() throws JSQLParserException { - String sql = "SELECT last_name, employee_id, manager_id, LEVEL FROM employees START WITH employee_id = 100 CONNECT BY PRIOR employee_id = manager_id ORDER SIBLINGS BY last_name"; + String sql = + "SELECT last_name, employee_id, manager_id, LEVEL FROM employees START WITH employee_id = 100 CONNECT BY PRIOR employee_id = manager_id ORDER SIBLINGS BY last_name"; validateNoErrors(sql, 1, DatabaseType.ORACLE); } @@ -127,7 +148,8 @@ public void testValidationWith() throws JSQLParserException { @Test public void testValidationWithRecursive() throws JSQLParserException { - String statement = "WITH RECURSIVE t (n) AS ((SELECT 1) UNION ALL (SELECT n + 1 FROM t WHERE n < 100)) SELECT sum(n) FROM t"; + String statement = + "WITH RECURSIVE t (n) AS ((SELECT 1) UNION ALL (SELECT n + 1 FROM t WHERE n < 100)) SELECT sum(n) FROM t"; validateNoErrors(statement, 1, DatabaseType.H2, DatabaseType.MARIADB, DatabaseType.MYSQL, DatabaseType.SQLSERVER, DatabaseType.POSTGRESQL); validateNotSupported(statement, 1, 1, DatabaseType.ORACLE, Feature.withItemRecursive); @@ -135,7 +157,8 @@ public void testValidationWithRecursive() throws JSQLParserException { @Test public void testSelectMulipleExpressionList() { - String sql = "SELECT * FROM mytable WHERE (SSN, SSM) IN (('11111111111111', '22222222222222'))"; + String sql = + "SELECT * FROM mytable WHERE (SSN, SSM) IN (('11111111111111', '22222222222222'))"; validateNoErrors(sql, 1, DatabaseType.DATABASES); } @@ -148,7 +171,8 @@ public void testValidatePivotWithAlias() throws JSQLParserException { @Test public void testValidatePivotXml() throws JSQLParserException { - validateNoErrors("SELECT * FROM mytable PIVOT XML (count(a) FOR b IN ('val1'))", 1, DatabaseType.SQLSERVER); + validateNoErrors("SELECT * FROM mytable PIVOT XML (count(a) FOR b IN ('val1'))", 1, + DatabaseType.SQLSERVER); } @Test @@ -160,14 +184,17 @@ public void testValidateUnPivot() throws JSQLParserException { @Test public void testValidateSubJoin() throws JSQLParserException { - validateNoErrors("SELECT * FROM ((tabc c INNER JOIN tabn n ON n.ref = c.id) INNER JOIN taba a ON a.REF = c.id)", + validateNoErrors( + "SELECT * FROM ((tabc c INNER JOIN tabn n ON n.ref = c.id) INNER JOIN taba a ON a.REF = c.id)", 1, DatabaseType.SQLSERVER); } @Test public void testValidateTableFunction() { - for (String sql : Arrays.asList("SELECT f2 FROM SOME_FUNCTION()", "SELECT f2 FROM SOME_FUNCTION(1, 'val')")) { - validateNoErrors(sql, 1, DatabaseType.POSTGRESQL, DatabaseType.H2, DatabaseType.SQLSERVER); + for (String sql : Arrays.asList("SELECT f2 FROM SOME_FUNCTION()", + "SELECT f2 FROM SOME_FUNCTION(1, 'val')")) { + validateNoErrors(sql, 1, DatabaseType.POSTGRESQL, DatabaseType.H2, + DatabaseType.SQLSERVER); } } @@ -182,11 +209,11 @@ public void testValidateLateral() throws JSQLParserException { public void testValidateIssue1502() throws JSQLParserException { validateNoErrors( "select b.id, name ,(select name from Blog where name = 'sadf') as name2 " - + ", category, owner, b.update_time " - + "from Blog as b " - + "left join Content " - + "ON b.id = Content.blog_id " - + "where name = 'sadf' order by Content.title desc", + + ", category, owner, b.update_time " + + "from Blog as b " + + "left join Content " + + "ON b.id = Content.blog_id " + + "where name = 'sadf' order by Content.title desc", 1, DatabaseType.POSTGRESQL); - } + } } diff --git a/src/test/java/net/sf/jsqlparser/util/validation/validator/StatementValidatorTest.java b/src/test/java/net/sf/jsqlparser/util/validation/validator/StatementValidatorTest.java index a17cb1087..7a7e52888 100644 --- a/src/test/java/net/sf/jsqlparser/util/validation/validator/StatementValidatorTest.java +++ b/src/test/java/net/sf/jsqlparser/util/validation/validator/StatementValidatorTest.java @@ -29,11 +29,19 @@ public void testValidateCreateSchema() throws JSQLParserException { @Test public void testValidateCreateSchemaNotAllowed() throws JSQLParserException { - for (String sql : Arrays.asList("CREATE SCHEMA my_schema", "CREATE SCHEMA myschema AUTHORIZATION myauth")) { + for (String sql : Arrays.asList("CREATE SCHEMA my_schema", + "CREATE SCHEMA myschema AUTHORIZATION myauth")) { validateNotAllowed(sql, 1, 1, FeaturesAllowed.DML, Feature.createSchema); } } + @Test + public void testValidateDescNoErrors() throws JSQLParserException { + for (String sql : Arrays.asList("DESC table_name", "EXPLAIN table_name")) { + validateNoErrors(sql, 1, DatabaseType.MYSQL); + } + } + @Test public void testValidateTruncate() throws JSQLParserException { validateNoErrors("TRUNCATE TABLE my_table", 1, DatabaseType.DATABASES); @@ -53,7 +61,8 @@ public void testValidateBlock() throws JSQLParserException { @Test public void testValidateComment() throws JSQLParserException { for (String sql : Arrays.asList("COMMENT ON VIEW myschema.myView IS 'myComment'", - "COMMENT ON COLUMN myTable.myColumn is 'Some comment'", "COMMENT ON TABLE table1 IS 'comment1'")) { + "COMMENT ON COLUMN myTable.myColumn is 'Some comment'", + "COMMENT ON TABLE table1 IS 'comment1'")) { validateNoErrors(sql, 1, DatabaseType.H2, DatabaseType.ORACLE, DatabaseType.POSTGRESQL); } } diff --git a/src/test/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidatorTest.java b/src/test/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidatorTest.java new file mode 100644 index 000000000..c71b8448e --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/util/validation/validator/TableStatementValidatorTest.java @@ -0,0 +1,38 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2020 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.util.validation.validator; + +import java.util.Arrays; +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.parser.feature.Feature; +import net.sf.jsqlparser.util.validation.ValidationTestAsserts; +import net.sf.jsqlparser.util.validation.feature.FeaturesAllowed; +import net.sf.jsqlparser.util.validation.feature.MySqlVersion; +import net.sf.jsqlparser.util.validation.feature.PostgresqlVersion; +import org.junit.jupiter.api.Test; + +public class TableStatementValidatorTest extends ValidationTestAsserts { + + @Test + public void testValidationSelectAllowed() throws JSQLParserException { + String sql = "TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10"; + validateNoErrors(sql, 1, MySqlVersion.V8_0); + } + + @Test + public void testValidationSelectNotAllowed() throws JSQLParserException { + String sql = "TABLE columns ORDER BY column_name LIMIT 10 OFFSET 10"; + validateNotAllowed(sql, 1, 1, FeaturesAllowed.DDL, Feature.select, Feature.tableStatement); + + validateNotSupported(sql, 1, 1, Arrays.asList( + PostgresqlVersion.V14), Feature.tableStatement); + } + +} diff --git a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/explain01.sql b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/explain01.sql index d4fc556bd..c60faf151 100644 --- a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/explain01.sql +++ b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/explain01.sql @@ -16,4 +16,5 @@ explain plan (select department_id from departments where location_id = 1700) ---@FAILURE: Encountered unexpected token: "plan" recorded first on Aug 3, 2021, 7:20:08 AM \ No newline at end of file +--@FAILURE: Encountered unexpected token: "plan" recorded first on Aug 3, 2021, 7:20:08 AM +--@FAILURE: Encountered unexpected token: "set" "SET" recorded first on 2023年12月23日 下午1:38:33 \ No newline at end of file diff --git a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/merge03.sql b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/merge03.sql index 4afaac31e..ca021f1c2 100644 --- a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/merge03.sql +++ b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/merge03.sql @@ -25,4 +25,5 @@ update set mm.inserts = mm.inserts + v.inserts, mm.updates = mm.updates + v.upda mm.flags = mm.flags + v.flags - bitand(mm.flags,v.flags) , mm.drop_segments = mm.drop_segments + v.drop_segments when not matched then insert values (v.obj#, v.inserts, v.updates, v.deletes, sysdate, v.flags, v.drop_segments) ---@FAILURE: merge into sys.mon_mods_all$ mm using(select decode(grouping_id(tp.bo#,tsp.pobj#,m.obj#),3,tp.bo#,1,tsp.pobj#,m.obj#)obj#,sum(m.inserts)inserts,sum(m.updates)updates,sum(m.deletes)deletes,decode(sum(bitand(m.flags,1)),0,0,1)+decode(sum(bitand(m.flags,2)),0,0,2)+decode(sum(bitand(m.flags,4)),0,0,4)flags,sum(m.drop_segments)drop_segments from sys.mon_mods$ m,sys.tabcompart$ tp,sys.tabsubpart$ tsp where m.obj#=tsp.obj# and tp.obj#=tsp.pobj# group by rollup(tp.bo#,tsp.pobj#,m.obj#)having grouping_id(tp.bo#,tsp.pobj#,m.obj#)<7)v on(mm.obj#=v.obj#)when matched then update set mm.inserts=mm.inserts+v.inserts,mm.updates=mm.updates+v.updates,mm.deletes=mm.deletes+v.deletes,mm.flags=mm.flags+v.flags-bitand(mm.flags,v.flags),mm.drop_segments=mm.drop_segments+v.drop_segments when not matched then insert values(v.obj#,v.inserts,v.updates,v.deletes,sysdate,v.flags,v.drop_segments) recorded first on Aug 3, 2021, 7:20:08 AM \ No newline at end of file +--@FAILURE: merge into sys.mon_mods_all$ mm using(select decode(grouping_id(tp.bo#,tsp.pobj#,m.obj#),3,tp.bo#,1,tsp.pobj#,m.obj#)obj#,sum(m.inserts)inserts,sum(m.updates)updates,sum(m.deletes)deletes,decode(sum(bitand(m.flags,1)),0,0,1)+decode(sum(bitand(m.flags,2)),0,0,2)+decode(sum(bitand(m.flags,4)),0,0,4)flags,sum(m.drop_segments)drop_segments from sys.mon_mods$ m,sys.tabcompart$ tp,sys.tabsubpart$ tsp where m.obj#=tsp.obj# and tp.obj#=tsp.pobj# group by rollup(tp.bo#,tsp.pobj#,m.obj#)having grouping_id(tp.bo#,tsp.pobj#,m.obj#)<7)v on(mm.obj#=v.obj#)when matched then update set mm.inserts=mm.inserts+v.inserts,mm.updates=mm.updates+v.updates,mm.deletes=mm.deletes+v.deletes,mm.flags=mm.flags+v.flags-bitand(mm.flags,v.flags),mm.drop_segments=mm.drop_segments+v.drop_segments when not matched then insert values(v.obj#,v.inserts,v.updates,v.deletes,sysdate,v.flags,v.drop_segments) recorded first on Aug 3, 2021, 7:20:08 AM +--@SUCCESSFULLY_PARSED_AND_DEPARSED first on 18 Dec 2023, 17:18:40 \ No newline at end of file diff --git a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/merge04.sql b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/merge04.sql index 403806403..a4b80ac0b 100644 --- a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/merge04.sql +++ b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/merge04.sql @@ -26,4 +26,5 @@ update set mm.inserts = mm.inserts + v.inserts, mm.updates = mm.updates + v.upda mm.flags = mm.flags + v.flags - bitand(mm.flags,v.flags) , mm.drop_segments = mm.drop_segments + v.drop_segments when not matched then insert values (v.obj#, v.inserts, v.updates, v.deletes, sysdate, v.flags, v.drop_segments) ---@FAILURE: merge into sys.mon_mods_all$ mm using(select decode(grouping_id(tp.bo#,tsp.pobj#,m.obj#),3,tp.bo#,1,tsp.pobj#,m.obj#)obj#,sum(m.inserts)inserts,sum(m.updates)updates,sum(m.deletes)deletes,decode(sum(bitand(m.flags,1)),0,0,1)+decode(sum(bitand(m.flags,2)),0,0,2)+decode(sum(bitand(m.flags,4)),0,0,4)flags,sum(m.drop_segments)drop_segments from sys.mon_mods$ m,sys.tabcompart$ tp,sys.tabsubpart$ tsp where m.obj#=tsp.obj# and tp.obj#=tsp.pobj# group by rollup(tp.bo#,tsp.pobj#,m.obj#)having grouping_id(tp.bo#,tsp.pobj#,m.obj#)<7 order by 1,2,3)v on(mm.obj#=v.obj#)when matched then update set mm.inserts=mm.inserts+v.inserts,mm.updates=mm.updates+v.updates,mm.deletes=mm.deletes+v.deletes,mm.flags=mm.flags+v.flags-bitand(mm.flags,v.flags),mm.drop_segments=mm.drop_segments+v.drop_segments when not matched then insert values(v.obj#,v.inserts,v.updates,v.deletes,sysdate,v.flags,v.drop_segments) recorded first on Aug 3, 2021, 7:20:08 AM \ No newline at end of file +--@FAILURE: merge into sys.mon_mods_all$ mm using(select decode(grouping_id(tp.bo#,tsp.pobj#,m.obj#),3,tp.bo#,1,tsp.pobj#,m.obj#)obj#,sum(m.inserts)inserts,sum(m.updates)updates,sum(m.deletes)deletes,decode(sum(bitand(m.flags,1)),0,0,1)+decode(sum(bitand(m.flags,2)),0,0,2)+decode(sum(bitand(m.flags,4)),0,0,4)flags,sum(m.drop_segments)drop_segments from sys.mon_mods$ m,sys.tabcompart$ tp,sys.tabsubpart$ tsp where m.obj#=tsp.obj# and tp.obj#=tsp.pobj# group by rollup(tp.bo#,tsp.pobj#,m.obj#)having grouping_id(tp.bo#,tsp.pobj#,m.obj#)<7 order by 1,2,3)v on(mm.obj#=v.obj#)when matched then update set mm.inserts=mm.inserts+v.inserts,mm.updates=mm.updates+v.updates,mm.deletes=mm.deletes+v.deletes,mm.flags=mm.flags+v.flags-bitand(mm.flags,v.flags),mm.drop_segments=mm.drop_segments+v.drop_segments when not matched then insert values(v.obj#,v.inserts,v.updates,v.deletes,sysdate,v.flags,v.drop_segments) recorded first on Aug 3, 2021, 7:20:08 AM +--@SUCCESSFULLY_PARSED_AND_DEPARSED first on 18 Dec 2023, 17:18:40 \ No newline at end of file diff --git a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/model_clause12.sql b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/model_clause12.sql index 5a5dfb3c7..8201dcabe 100644 --- a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/model_clause12.sql +++ b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/model_clause12.sql @@ -26,4 +26,5 @@ level2[any] = case when org_level[cv()] = 2 then ename [cv()] end, level3[any] = case when org_level[cv()] = 3 then ename [cv()] end, level4[any] = case when org_level[cv()] = 4 then ename [cv()] end ) ---@FAILURE: Encountered unexpected token: "return" recorded first on Aug 3, 2021, 7:20:08 AM \ No newline at end of file +--@FAILURE: Encountered unexpected token: "return" recorded first on Aug 3, 2021, 7:20:08 AM +--@FAILURE: Encountered unexpected token: "return" "RETURN" recorded first on 9 Dec 2023, 18:20:45 \ No newline at end of file diff --git a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/model_clause13.sql b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/model_clause13.sql index 0e5f1026e..e9e35ce56 100644 --- a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/model_clause13.sql +++ b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/model_clause13.sql @@ -30,4 +30,5 @@ level3[any] = case when org_level[cv()] = 3 then ename [cv()] end, level4[any] = case when org_level[cv()] = 4 then ename [cv()] end ))) ---@FAILURE: Encountered unexpected token: "return" recorded first on Aug 3, 2021, 7:20:08 AM \ No newline at end of file +--@FAILURE: Encountered unexpected token: "return" recorded first on Aug 3, 2021, 7:20:08 AM +--@FAILURE: Encountered unexpected token: "return" "RETURN" recorded first on 9 Dec 2023, 18:20:44 \ No newline at end of file