StructType.java
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2024 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.expression;
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
import net.sf.jsqlparser.statement.create.table.ColDataType;
import net.sf.jsqlparser.statement.select.SelectItem;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/*
* STRUCT<T>
*
* Type Declaration Meaning STRUCT<INT64> Simple struct with a single unnamed 64-bit integer field.
* STRUCT<x STRING(10)> Simple struct with a single parameterized string field named x. STRUCT<x
* STRUCT<y INT64, z INT64>> A struct with a nested struct named x inside it. The struct x has two
* fields, y and z, both of which are 64-bit integers. STRUCT<inner_array ARRAY<INT64>> A struct
* containing an array named inner_array that holds 64-bit integer elements.
*
* STRUCT( expr1 [AS field_name] [, ... ])
*
* Syntax Output Type STRUCT(1,2,3) STRUCT<int64,int64,int64> STRUCT() STRUCT<> STRUCT('abc')
* STRUCT<string> STRUCT(1, t.str_col) STRUCT<int64, str_col string> STRUCT(1 AS a, 'abc' AS b)
* STRUCT<a int64, b string> STRUCT(str_col AS abc) STRUCT<abc string>
*
*
* Struct Literals
*
* Example Output Type (1, 2, 3) STRUCT<INT64, INT64, INT64> (1, 'abc') STRUCT<INT64, STRING>
* STRUCT(1 AS foo, 'abc' AS bar) STRUCT<foo INT64, bar STRING> STRUCT<INT64, STRING>(1, 'abc')
* STRUCT<INT64, STRING> STRUCT(1) STRUCT<INT64> STRUCT<INT64>(1) STRUCT<INT64>
*
*/
public class StructType extends ASTNodeAccessImpl implements Expression {
private Dialect dialect = Dialect.BIG_QUERY;;
private String keyword;
private List<Map.Entry<String, ColDataType>> parameters;
private List<SelectItem<?>> arguments;
public StructType(Dialect dialect, String keyword,
List<Map.Entry<String, ColDataType>> parameters,
List<SelectItem<?>> arguments) {
this.dialect = dialect;
this.keyword = keyword;
this.parameters = parameters;
this.arguments = arguments;
}
public StructType(Dialect dialect, List<Map.Entry<String, ColDataType>> parameters,
List<SelectItem<?>> arguments) {
this.dialect = dialect;
this.parameters = parameters;
this.arguments = arguments;
}
public StructType(Dialect dialect, List<SelectItem<?>> arguments) {
this.dialect = dialect;
this.arguments = arguments;
}
public Dialect getDialect() {
return dialect;
}
public StructType setDialect(Dialect dialect) {
this.dialect = dialect;
return this;
}
public String getKeyword() {
return keyword;
}
public StructType setKeyword(String keyword) {
this.keyword = keyword;
return this;
}
public List<Map.Entry<String, ColDataType>> getParameters() {
return parameters;
}
public StructType setParameters(List<Map.Entry<String, ColDataType>> parameters) {
this.parameters = parameters;
return this;
}
public List<SelectItem<?>> getArguments() {
return arguments;
}
public StructType setArguments(List<SelectItem<?>> arguments) {
this.arguments = arguments;
return this;
}
public StructType add(Expression expression, String aliasName) {
if (arguments == null) {
arguments = new ArrayList<>();
}
arguments.add(new SelectItem<>(expression, aliasName));
return this;
}
public StringBuilder appendTo(StringBuilder builder) {
if (dialect != Dialect.DUCKDB && keyword != null) {
builder.append(keyword);
}
if (dialect != Dialect.DUCKDB && parameters != null && !parameters.isEmpty()) {
builder.append("<");
int i = 0;
for (Map.Entry<String, ColDataType> e : parameters) {
if (0 < i++) {
builder.append(",");
}
// optional name
if (e.getKey() != null && !e.getKey().isEmpty()) {
builder.append(e.getKey()).append(" ");
}
// mandatory type
builder.append(e.getValue());
}
builder.append(">");
}
if (arguments != null && !arguments.isEmpty()) {
if (dialect == Dialect.DUCKDB) {
builder.append("{ ");
int i = 0;
for (SelectItem<?> e : arguments) {
if (0 < i++) {
builder.append(",");
}
builder.append(e.getAlias().getName());
builder.append(":");
builder.append(e.getExpression());
}
builder.append(" }");
} else {
builder.append("(");
int i = 0;
for (SelectItem<?> e : arguments) {
if (0 < i++) {
builder.append(",");
}
e.appendTo(builder);
}
builder.append(")");
}
}
if (dialect == Dialect.DUCKDB && parameters != null && !parameters.isEmpty()) {
builder.append("::STRUCT( ");
int i = 0;
for (Map.Entry<String, ColDataType> e : parameters) {
if (0 < i++) {
builder.append(",");
}
builder.append(e.getKey()).append(" ");
builder.append(e.getValue());
}
builder.append(")");
}
return builder;
}
@Override
public String toString() {
return appendTo(new StringBuilder()).toString();
}
@Override
public <T, S> T accept(ExpressionVisitor<T> expressionVisitor, S context) {
return expressionVisitor.visit(this, context);
}
public enum Dialect {
BIG_QUERY, DUCKDB
}
}