use of com.questdb.ex.ParserException in project questdb by bluestreak01.
the class QueryCompiler method selectColumns0.
private RecordSource selectColumns0(final RecordSource recordSource, QueryModel model) throws ParserException {
final ObjList<QueryColumn> columns = model.getColumns();
final CharSequenceIntHashMap columnNameHistogram = model.getColumnNameHistogram();
final RecordMetadata meta = recordSource.getMetadata();
this.outerVirtualColumns.clear();
this.innerVirtualColumn.clear();
this.aggregators.clear();
this.selectedColumns.clear();
this.selectedColumnAliases.clear();
this.groupKeyColumns.clear();
this.aggregateColumnSequence = 0;
this.analyticColumns.clear();
RecordSource rs = recordSource;
try {
// create virtual columns from select list
for (int i = 0, k = columns.size(); i < k; i++) {
final QueryColumn qc = columns.getQuick(i);
final ExprNode node = qc.getAst();
final boolean analytic = qc instanceof AnalyticColumn;
if (!analytic && node.type == ExprNode.LITERAL) {
// check literal column validity
if (meta.getColumnIndexQuiet(node.token) == -1) {
throw QueryError.invalidColumn(node.position, node.token);
}
// check if this column is exists in more than one journal/result set
if (columnNameHistogram.get(node.token) > 0) {
throw QueryError.ambiguousColumn(node.position);
}
// add to selected columns
selectedColumns.add(node.token);
addAlias(node.position, qc.getName());
groupKeyColumns.add(node.token);
continue;
}
// generate missing alias for everything else
if (qc.getAlias() == null) {
qc.of(createAlias(aggregateColumnSequence++), node.position, node);
}
selectedColumns.add(qc.getAlias());
addAlias(node.position, qc.getAlias());
// outright aggregate
if (!analytic && node.type == ExprNode.FUNCTION && FunctionFactories.isAggregate(node.token)) {
aggregators.add(qc);
continue;
}
// check if this expression references aggregate function
if (node.type == ExprNode.OPERATION || node.type == ExprNode.FUNCTION) {
int beforeSplit = aggregators.size();
splitAggregates(node, aggregators);
if (beforeSplit < aggregators.size()) {
outerVirtualColumns.add(qc);
continue;
}
}
if (analytic) {
if (qc.getAst().type != ExprNode.FUNCTION) {
// todo: not hit by test
throw QueryError.$(qc.getAst().position, "Analytic function expected");
}
if (aggregators.size() > 0) {
throw QueryError.$(qc.getAst().position, "Analytic function is not allowed in context of aggregation. Use sub-query.");
}
AnalyticColumn ac = (AnalyticColumn) qc;
analyticColumns.add(ac);
} else {
// this is either a constant or non-aggregate expression
// either case is a virtual column
innerVirtualColumn.add(qc);
}
}
// if virtual columns are present, create record source to calculate them
if (innerVirtualColumn.size() > 0) {
// this is either a constant or non-aggregate expression
// either case is a virtual column
ObjList<VirtualColumn> virtualColumns = new ObjList<>();
final String timestampName;
if (model.getSampleBy() != null) {
timestampName = meta.getColumnName(getTimestampIndex(model, model.getTimestamp(), meta));
} else {
timestampName = null;
}
for (int i = 0, n = innerVirtualColumn.size(); i < n; i++) {
QueryColumn qc = innerVirtualColumn.getQuick(i);
if (Chars.equalsNc(qc.getAlias(), timestampName)) {
throw QueryError.$(qc.getAliasPosition() == -1 ? qc.getAst().position : qc.getAliasPosition(), "Alias clashes with implicit sample column name");
}
VirtualColumn vc = virtualColumnBuilder.createVirtualColumn(model, qc.getAst(), meta);
vc.setName(qc.getAlias());
virtualColumns.add(vc);
groupKeyColumns.add(qc.getAlias());
}
rs = new VirtualColumnRecordSource(rs, virtualColumns);
}
// if aggregators present, wrap record source into group-by source
if (aggregators.size() > 0) {
rs = compileAggregates(rs, model);
} else {
ExprNode sampleBy = model.getSampleBy();
if (sampleBy != null) {
throw QueryError.$(sampleBy.position, "There are no aggregation columns");
}
}
if (outerVirtualColumns.size() > 0) {
rs = compileOuterVirtualColumns(rs, model);
}
if (analyticColumns.size() > 0) {
rs = compileAnalytic(rs, model);
}
if (selectedColumns.size() > 0) {
// wrap underlying record source into selected columns source.
rs = new SelectedColumnsRecordSource(rs, selectedColumns, selectedColumnAliases);
}
return rs;
} catch (ParserException e) {
Misc.free(rs);
throw e;
}
}
use of com.questdb.ex.ParserException in project questdb by bluestreak01.
the class QueryCompiler method compileNoOptimise.
private RecordSource compileNoOptimise(QueryModel model, Factory factory) throws ParserException {
RecordSource rs;
try {
if (model.getJoinModels().size() > 1) {
optimiseJoins(model, factory);
rs = compileJoins(model, factory);
} else if (model.getJournalName() != null) {
rs = compileJournal(model, factory);
} else {
rs = compileSubQuery(model, factory);
QueryModel nm = model.getNestedModel();
if (nm != null) {
nm.setRecordSource(rs);
}
}
return limit(timestamp(order(selectColumns(rs, model), model), model), model);
} catch (ParserException e) {
freeModelRecordSources(model);
throw e;
}
}
Aggregations