All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
ma.vi.esql.parser.query.Column Maven / Gradle / Ivy
/*
* Copyright (c) 2020 Vikash Madhow
*/
package ma.vi.esql.parser.query;
import ma.vi.base.string.Strings;
import ma.vi.base.tuple.T2;
import ma.vi.esql.parser.Context;
import ma.vi.esql.parser.Esql;
import ma.vi.esql.parser.MetadataContainer;
import ma.vi.esql.parser.QueryUpdate;
import ma.vi.esql.parser.define.Attribute;
import ma.vi.esql.parser.define.ColumnDefinition;
import ma.vi.esql.parser.define.DerivedColumnDefinition;
import ma.vi.esql.parser.define.Metadata;
import ma.vi.esql.parser.expression.BooleanLiteral;
import ma.vi.esql.parser.expression.ColumnRef;
import ma.vi.esql.parser.expression.Expression;
import ma.vi.esql.parser.expression.StringLiteral;
import ma.vi.esql.type.BaseRelation;
import ma.vi.esql.type.Type;
import ma.vi.esql.type.Types;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
import static ma.vi.esql.builder.Attributes.*;
import static ma.vi.esql.parser.Translatable.Target.ESQL;
/**
* A column in a select statement.
*
* @author Vikash Madhow ([email protected] )
*/
public class Column extends MetadataContainer, String> {
public Column(Context context,
String alias,
Expression expr,
Metadata metadata) {
super(context,
expr,
T2.of("alias", new Esql<>(context, alias)),
T2.of("metadata", metadata));
/*
* Alias with referenced column name if not already aliased.
*/
if (alias == null) {
if (expr instanceof ColumnRef) {
alias(((ColumnRef)expr).name());
} else {
alias("__auto_col_" + Strings.random(10));
}
}
}
public Column(Column other) {
super(other);
}
public static Column fromDefinition(ColumnDefinition def) {
boolean derived = def instanceof DerivedColumnDefinition;
DerivedColumnDefinition derivedDef = derived ? (DerivedColumnDefinition)def : null;
Type columnType = null;
if (!derived) {
columnType = def.type();
}
Boolean notNull = def.notNull();
Expression defaultExpr = def.expression();
Column col = new Column(def.context,
def.name(),
derived ? derivedDef.expression() : new ColumnRef(def.context, null, def.name()),
def.metadata());
col.id(UUID.randomUUID());
if (derived) {
col.attribute(DERIVED, new BooleanLiteral(def.context, true));
} else if (defaultExpr != null) {
col.attribute(EXPRESSION, defaultExpr);
}
col.attribute(TYPE, new StringLiteral(def.context,
derived ? Types.VoidType.translate(ESQL)
: "'" + columnType.translate(ESQL) + "'"));
if (notNull) {
col.attribute(REQUIRED, new BooleanLiteral(def.context, true));
}
return col;
}
@Override
public Column copy() {
if (!copying()) {
try {
copying(true);
return new Column(this);
} finally {
copying(false);
}
} else {
return this;
}
}
@Override
protected String trans(Target target, Map parameters) {
if (target == ESQL) {
StringBuilder st = new StringBuilder();
if (alias() != null) {
st.append(alias()).append(':');
}
st.append(expr().translate(target, parameters));
Metadata metadata = metadata();
if (metadata != null && !metadata.attributes().isEmpty()) {
st.append(" {");
boolean first = true;
for (Attribute attr: metadata.attributes().values()) {
if (first) { first = false; }
else { st.append(", "); }
st.append(attr.name()).append(':')
.append(attr.attributeValue().translate(target, parameters));
}
st.append('}');
}
return st.toString();
} else {
StringBuilder st = new StringBuilder(expr().translate(target, parameters));
if (alias() != null) {
st.append(" \"").append(alias()).append('"');
}
return st.toString();
}
}
public boolean derived() {
if (metadata() != null) {
Boolean derived = metadata().evaluateAttribute(DERIVED);
return derived != null && derived;
}
return false;
}
public boolean notNull() {
if (metadata() != null) {
Object notNull = metadata().evaluateAttribute(REQUIRED);
return notNull instanceof Boolean && (Boolean)notNull;
}
return false;
}
public void notNull(boolean notNull) {
if (metadata() == null) {
metadata(new Metadata(context, new ArrayList<>()));
}
metadata().attribute(REQUIRED, new BooleanLiteral(context, notNull));
}
public UUID id() {
if (metadata() != null && metadata().attribute(ID) != null) {
return metadata().evaluateAttribute(ID);
} else {
return null;
}
}
public void id(UUID id) {
if (metadata() == null) {
metadata(new Metadata(context, new ArrayList<>()));
}
metadata().attribute(ID, id);
}
public Expression defaultExpression() {
if (metadata() != null
&& metadata().attribute(EXPRESSION) != null) {
return metadata().attribute(EXPRESSION).attributeValue();
} else {
return null;
}
}
public void defaultExpression(Expression expr) {
if (metadata() == null) {
metadata(new Metadata(context, new ArrayList<>()));
}
metadata().attribute(EXPRESSION, expr);
}
@Override
public void attribute(String name, Expression value) {
if (metadata() == null) {
metadata(new Metadata(context, new ArrayList<>()));
}
if (value != null && parent != null && parent.value instanceof BaseRelation) {
value = ((BaseRelation)parent.value).expandDerived(value,name, new HashSet<>());
}
metadata().attribute(name, value);
}
@Override
public Type type() {
if (metadata() != null && metadata().attribute(TYPE) != null) {
Type type = Types.typeOf((String)metadata().evaluateAttribute(TYPE));
if (type == Types.VoidType && derived()) {
/*
* Derived type are set to void on load. Their actual types can
* be determined at this point.
*/
type = expr().type();
if (type != Types.VoidType) {
type(type);
/*
* Transfer the type information to base table if possible.
*/
QueryUpdate query = ancestor(QueryUpdate.class);
if (query != null && query.tables() instanceof SingleTableExpr) {
SingleTableExpr table = (SingleTableExpr)query.tables();
if (context.structure.relationExists(table.tableName())) {
BaseRelation rel = context.structure.relation(table.tableName());
if (rel.findColumn(null, alias()) != null) {
Column column = rel.column(null, alias());
column.type(type);
}
}
}
}
}
return type;
} else {
Type type = expr().type();
type(type);
return type;
}
}
public void type(Type type) {
if (metadata() == null) {
metadata(new Metadata(context, new ArrayList<>()));
}
metadata().attribute(TYPE, new StringLiteral(context, type.translate(ESQL)));
}
@Override
public void _toString(StringBuilder st, int level, int indent) {
if (alias() != null) {
st.append(alias()).append(':');
}
st.append(expr());
if (metadata() != null && !metadata().attributes().isEmpty()) {
metadata()._toString(st, level, indent);
}
}
public Expression expr() {
return value;
}
public void expr(Expression expr) {
value = expr;
}
public String alias() {
return childValue("alias");
}
public void alias(String alias) {
((Esql)child("alias")).value = alias;
}
}