Skip to content
Open
81 changes: 81 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/AssertStatement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2026 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.statement;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;

/**
* BigQuery's {@code ASSERT expression [AS description]}, which fails the script when the expression
* does not evaluate to {@code TRUE}.
*
* @see <a href=
* "https://cloud.google.com/bigquery/docs/reference/standard-sql/debugging-statements">Debugging
* statements</a>
*/
public class AssertStatement implements Statement {
private Expression expression;
private StringValue description;

public AssertStatement() {}

public AssertStatement(Expression expression) {
this.expression = expression;
}

public AssertStatement(Expression expression, StringValue description) {
this.expression = expression;
this.description = description;
}

public Expression getExpression() {
return expression;
}

public void setExpression(Expression expression) {
this.expression = expression;
}

public AssertStatement withExpression(Expression expression) {
setExpression(expression);
return this;
}

public StringValue getDescription() {
return description;
}

public void setDescription(StringValue description) {
this.description = description;
}

public AssertStatement withDescription(StringValue description) {
setDescription(description);
return this;
}

public StringBuilder appendTo(StringBuilder builder) {
builder.append("ASSERT ").append(expression);
if (description != null) {
builder.append(" AS ").append(description);
}
return builder;
}

@Override
public String toString() {
return appendTo(new StringBuilder()).toString();
}

@Override
public <T, S> T accept(StatementVisitor<T> statementVisitor, S context) {
return statementVisitor.visit(this, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@
import java.util.Locale;
import java.util.Set;
import java.util.function.Predicate;
import net.sf.jsqlparser.statement.export.ExportDataStatement;
import net.sf.jsqlparser.statement.load.LoadDataStatement;

/**
* Derives a {@link StatementFeatures} verdict from a statement tree.
Expand Down Expand Up @@ -521,6 +523,27 @@ public <S> Void visit(Drop drop, S context) {
return null;
}

@Override
public <S> Void visit(AssertStatement assertStatement, S context) {
analysis.claimTopLevel();
analysis.certain(StmtFeature.READS_DATA);
return null;
}

@Override
public <S> Void visit(ExportDataStatement exportDataStatement, S context) {
analysis.claimTopLevel();
analysis.certain(StmtFeature.READS_DATA, StmtFeature.MODIFIES_DATA);
return null;
}

@Override
public <S> Void visit(LoadDataStatement loadDataStatement, S context) {
analysis.claimTopLevel();
analysis.certain(StmtFeature.MODIFIES_DATA);
return null;
}

@Override
public <S> Void visit(PurgeStatement purgeStatement, S context) {
analysis.claimTopLevel();
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
import net.sf.jsqlparser.statement.update.ParenthesedUpdate;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.upsert.Upsert;
import net.sf.jsqlparser.statement.export.ExportDataStatement;
import net.sf.jsqlparser.statement.load.LoadDataStatement;

public interface StatementVisitor<T> {

Expand Down Expand Up @@ -371,6 +373,24 @@ default void visit(RenameTableStatement renameTableStatement) {
this.visit(renameTableStatement, null);
}

<S> T visit(AssertStatement assertStatement, S context);

default void visit(AssertStatement assertStatement) {
this.visit(assertStatement, null);
}

<S> T visit(ExportDataStatement exportDataStatement, S context);

default void visit(ExportDataStatement exportDataStatement) {
this.visit(exportDataStatement, null);
}

<S> T visit(LoadDataStatement loadDataStatement, S context);

default void visit(LoadDataStatement loadDataStatement) {
this.visit(loadDataStatement, null);
}

<S> T visit(PurgeStatement purgeStatement, S context);

default void visit(PurgeStatement purgeStatement) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@

import java.util.List;
import net.sf.jsqlparser.util.TableDefinitionTraversal;
import net.sf.jsqlparser.statement.export.ExportDataStatement;
import net.sf.jsqlparser.statement.load.LoadDataStatement;

@SuppressWarnings({"PMD.UncommentedEmptyMethodBody"})
public class StatementVisitorAdapter<T> implements StatementVisitor<T> {
Expand Down Expand Up @@ -618,6 +620,21 @@ public <S> T visit(RenameTableStatement renameTableStatement, S context) {
return null;
}

@Override
public <S> T visit(AssertStatement assertStatement, S context) {
return null;
}

@Override
public <S> T visit(ExportDataStatement exportDataStatement, S context) {
return null;
}

@Override
public <S> T visit(LoadDataStatement loadDataStatement, S context) {
return null;
}

@Override
public <S> T visit(PurgeStatement purgeStatement, S context) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class CreateTable implements Statement {
private List<TableElement> tableElements;
private Select select;
private Table likeTable;
private Table cloneTable;
private ColDataType ofType;
private boolean selectParenthesis;
private boolean ifNotExists = false;
Expand Down Expand Up @@ -236,6 +237,22 @@ public void setLikeTable(Table likeTable, boolean parenthesis) {
this.selectParenthesis = parenthesis;
}

/**
* BigQuery's {@code CREATE [SNAPSHOT] TABLE target CLONE source [FOR SYSTEM_TIME AS OF ...]}.
*/
public Table getCloneTable() {
return cloneTable;
}

public void setCloneTable(Table cloneTable) {
this.cloneTable = cloneTable;
}

public CreateTable withCloneTable(Table cloneTable) {
setCloneTable(cloneTable);
return this;
}

public boolean isIfNotExists() {
return ifNotExists;
}
Expand Down Expand Up @@ -330,6 +347,9 @@ private void appendCreateClause(StringBuilder b) {
if (partitionOf != null) {
b.append(" PARTITION OF ").append(partitionOf);
}
if (cloneTable != null) {
b.append(" CLONE ").append(cloneTable);
}
}

private void appendColumnDefinitions(StringBuilder b) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@
public class TablePartitioning implements Serializable {

public enum Type {
HASH, KEY, RANGE, LIST
HASH, KEY, RANGE, LIST,
/**
* BigQuery partitions by a bare expression, without a partitioning method keyword:
* {@code PARTITION BY DATE(ts)}.
*/
EXPRESSION
}

private Type type;
Expand Down Expand Up @@ -285,6 +290,10 @@ public void appendTo(StringBuilder builder, Consumer<Expression> expressionPrint
}

private void appendMethod(StringBuilder builder, Consumer<Expression> expressionPrinter) {
if (type == Type.EXPRESSION) {
expressionPrinter.accept(expression);
return;
}
if (linear) {
builder.append("LINEAR ");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2026 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.statement.export;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.StatementVisitor;
import net.sf.jsqlparser.statement.select.Select;

/**
* BigQuery's {@code EXPORT DATA [WITH CONNECTION connection] OPTIONS (option_list) AS query}.
*
* @see <a href=
* "https://cloud.google.com/bigquery/docs/reference/standard-sql/export-statements">Export
* statements</a>
*/
public class ExportDataStatement implements Statement {
private String connectionName;
private ExpressionList<Expression> options;
private Select select;

public String getConnectionName() {
return connectionName;
}

public void setConnectionName(String connectionName) {
this.connectionName = connectionName;
}

public ExportDataStatement withConnectionName(String connectionName) {
setConnectionName(connectionName);
return this;
}

public ExpressionList<Expression> getOptions() {
return options;
}

public void setOptions(ExpressionList<Expression> options) {
this.options = options;
}

public ExportDataStatement withOptions(ExpressionList<Expression> options) {
setOptions(options);
return this;
}

public Select getSelect() {
return select;
}

public void setSelect(Select select) {
this.select = select;
}

public ExportDataStatement withSelect(Select select) {
setSelect(select);
return this;
}

public StringBuilder appendTo(StringBuilder builder) {
builder.append("EXPORT DATA");
if (connectionName != null) {
builder.append(" WITH CONNECTION ").append(connectionName);
}
if (options != null) {
builder.append(" OPTIONS (").append(options).append(")");
}
builder.append(" AS ").append(select);
return builder;
}

@Override
public String toString() {
return appendTo(new StringBuilder()).toString();
}

@Override
public <T, S> T accept(StatementVisitor<T> statementVisitor, S context) {
return statementVisitor.visit(this, context);
}
}
Loading
Loading