Search in sources :

Example 1 with QueryModel

use of io.questdb.griffin.model.QueryModel in project questdb by bluestreak01.

the class SqlCodeGenerator method generateSelectDistinct.

private RecordCursorFactory generateSelectDistinct(QueryModel model, SqlExecutionContext executionContext) throws SqlException {
    QueryModel twoDeepNested;
    ExpressionNode tableNameEn;
    if (model.getColumns().size() == 1 && model.getNestedModel() != null && model.getNestedModel().getSelectModelType() == QueryModel.SELECT_MODEL_CHOOSE && (twoDeepNested = model.getNestedModel().getNestedModel()) != null && twoDeepNested.getWhereClause() == null && twoDeepNested.getLatestBy().size() == 0 && (tableNameEn = twoDeepNested.getTableName()) != null) {
        CharSequence tableName = tableNameEn.token;
        try (TableReader reader = engine.getReader(executionContext.getCairoSecurityContext(), tableName)) {
            CharSequence columnName = model.getBottomUpColumnNames().get(0);
            TableReaderMetadata readerMetadata = reader.getMetadata();
            int columnIndex = readerMetadata.getColumnIndex(columnName);
            int columnType = readerMetadata.getColumnType(columnIndex);
            if (readerMetadata.getVersion() >= 416 && ColumnType.isSymbol(columnType)) {
                final GenericRecordMetadata distinctSymbolMetadata = new GenericRecordMetadata();
                distinctSymbolMetadata.add(BaseRecordMetadata.copyOf(readerMetadata, columnIndex));
                return new DistinctSymbolRecordCursorFactory(engine, distinctSymbolMetadata, Chars.toString(tableName), columnIndex, reader.getMetadata().getId(), reader.getVersion());
            }
        }
    }
    final RecordCursorFactory factory = generateSubQuery(model, executionContext);
    try {
        if (factory.recordCursorSupportsRandomAccess() && factory.getMetadata().getTimestampIndex() != -1) {
            return new DistinctTimeSeriesRecordCursorFactory(configuration, factory, entityColumnFilter, asm);
        }
        return new DistinctRecordCursorFactory(configuration, factory, entityColumnFilter, asm);
    } catch (Throwable e) {
        factory.close();
        throw e;
    }
}
Also used : SortedLightRecordCursorFactory(io.questdb.griffin.engine.orderby.SortedLightRecordCursorFactory) SortedRecordCursorFactory(io.questdb.griffin.engine.orderby.SortedRecordCursorFactory) LimitRecordCursorFactory(io.questdb.griffin.engine.LimitRecordCursorFactory) GroupByRecordCursorFactory(io.questdb.griffin.engine.groupby.vect.GroupByRecordCursorFactory) EmptyTableRecordCursorFactory(io.questdb.griffin.engine.EmptyTableRecordCursorFactory) CachedAnalyticRecordCursorFactory(io.questdb.griffin.engine.analytic.CachedAnalyticRecordCursorFactory) QueryModel(io.questdb.griffin.model.QueryModel)

Example 2 with QueryModel

use of io.questdb.griffin.model.QueryModel in project questdb by bluestreak01.

the class SqlParserTest method testTooManyColumnsEdgeInOrderBy.

@Test
public void testTooManyColumnsEdgeInOrderBy() throws Exception {
    try (TableModel model = modelOf("x")) {
        for (int i = 0; i < SqlParser.MAX_ORDER_BY_COLUMNS - 1; i++) {
            model.col("f" + i, ColumnType.INT);
        }
        CairoTestUtils.create(model);
    }
    StringBuilder b = new StringBuilder();
    b.append("x order by ");
    for (int i = 0; i < SqlParser.MAX_ORDER_BY_COLUMNS - 1; i++) {
        if (i > 0) {
            b.append(',');
        }
        b.append('f').append(i);
    }
    QueryModel st = (QueryModel) compiler.testCompileModel(b, sqlExecutionContext);
    Assert.assertEquals(SqlParser.MAX_ORDER_BY_COLUMNS - 1, st.getOrderBy().size());
}
Also used : QueryModel(io.questdb.griffin.model.QueryModel) Test(org.junit.Test)

Example 3 with QueryModel

use of io.questdb.griffin.model.QueryModel in project questdb by bluestreak01.

the class AbstractSqlParserTest method validateTopDownColumns.

private void validateTopDownColumns(QueryModel model) {
    ObjList<QueryColumn> columns = model.getColumns();
    final ObjList<LowerCaseCharSequenceHashSet> nameSets = new ObjList<>();
    QueryModel nested = model.getNestedModel();
    while (nested != null) {
        nameSets.clear();
        for (int i = 0, n = nested.getJoinModels().size(); i < n; i++) {
            LowerCaseCharSequenceHashSet set = new LowerCaseCharSequenceHashSet();
            final QueryModel m = nested.getJoinModels().getQuick(i);
            final ObjList<QueryColumn> cols = m.getTopDownColumns();
            for (int j = 0, k = cols.size(); j < k; j++) {
                QueryColumn qc = cols.getQuick(j);
                Assert.assertTrue(set.add(qc.getName()));
            }
            nameSets.add(set);
        }
        for (int i = 0, n = columns.size(); i < n; i++) {
            AbstractSqlParserTest.checkLiteralIsInSet(columns.getQuick(i).getAst(), nameSets, nested.getAliasIndexes());
        }
        columns = nested.getTopDownColumns();
        nested = nested.getNestedModel();
    }
}
Also used : QueryColumn(io.questdb.griffin.model.QueryColumn) QueryModel(io.questdb.griffin.model.QueryModel)

Example 4 with QueryModel

use of io.questdb.griffin.model.QueryModel in project questdb by bluestreak01.

the class GroupByUtils method validateGroupByColumns.

public static void validateGroupByColumns(@NotNull QueryModel model, int inferredKeyColumnCount) throws SqlException {
    final ObjList<ExpressionNode> groupByColumns = model.getGroupBy();
    int explicitKeyColumnCount = groupByColumns.size();
    if (explicitKeyColumnCount == 0) {
        return;
    }
    final QueryModel nested = model.getNestedModel();
    QueryModel chooseModel = model;
    while (chooseModel != null && chooseModel.getSelectModelType() != QueryModel.SELECT_MODEL_CHOOSE && chooseModel.getSelectModelType() != QueryModel.SELECT_MODEL_NONE) {
        chooseModel = chooseModel.getNestedModel();
    }
    for (int i = 0; i < explicitKeyColumnCount; i++) {
        final ExpressionNode key = groupByColumns.getQuick(i);
        switch(key.type) {
            case ExpressionNode.LITERAL:
                final int dotIndex = Chars.indexOf(key.token, '.');
                if (dotIndex > -1) {
                    int aliasIndex = model.getAliasIndex(key.token, 0, dotIndex);
                    if (aliasIndex > -1) {
                        // we should now check against main model
                        int refColumn = model.getAliasToColumnMap().keyIndex(key.token);
                        if (refColumn > -1) {
                            // a.x not found, look for "x"
                            refColumn = model.getAliasToColumnMap().keyIndex(key.token, dotIndex + 1, key.token.length());
                        }
                        if (refColumn > -1) {
                            throw SqlException.$(key.position, "group by column does not match any key column is select statement");
                        }
                    } else {
                        if (chooseModel != null && chooseModel.getColumnNameToAliasMap().keyIndex(key.token) < 0) {
                            continue;
                        }
                        throw SqlException.$(key.position, "invalid column reference");
                    }
                } else {
                    int refColumn = model.getAliasToColumnMap().keyIndex(key.token);
                    if (refColumn > -1) {
                        throw SqlException.$(key.position, "group by column does not match any key column is select statement");
                    }
                    QueryColumn qc = model.getAliasToColumnMap().valueAt(refColumn);
                    if (qc.getAst().type != ExpressionNode.LITERAL && qc.getAst().type != ExpressionNode.CONSTANT) {
                        throw SqlException.$(key.position, "group by column references aggregate expression");
                    }
                }
                break;
            case ExpressionNode.BIND_VARIABLE:
                throw SqlException.$(key.position, "bind variable is not allowed here");
            case ExpressionNode.FUNCTION:
            case ExpressionNode.OPERATION:
            case ExpressionNode.CONSTANT:
                final ObjList<QueryColumn> availableColumns = nested.getTopDownColumns();
                boolean invalid = true;
                for (int j = 0, n = availableColumns.size(); j < n; j++) {
                    final QueryColumn qc = availableColumns.getQuick(j);
                    if (qc.getAst().type == key.type) {
                        if (ExpressionNode.compareNodesGroupBy(key, qc.getAst(), chooseModel)) {
                            invalid = false;
                            break;
                        }
                    }
                }
                if (invalid) {
                    throw SqlException.$(key.position, "group by expression does not match anything select in statement");
                }
                break;
            default:
                throw SqlException.$(key.position, "unsupported type of expression");
        }
    }
    if (explicitKeyColumnCount < inferredKeyColumnCount) {
        throw SqlException.$(model.getModelPosition(), "not enough columns in group by");
    }
}
Also used : ExpressionNode(io.questdb.griffin.model.ExpressionNode) QueryColumn(io.questdb.griffin.model.QueryColumn) QueryModel(io.questdb.griffin.model.QueryModel)

Example 5 with QueryModel

use of io.questdb.griffin.model.QueryModel in project questdb by bluestreak01.

the class AbstractSqlParserTest method assertModel.

protected void assertModel(String expected, String query, int modelType, TableModel... tableModels) throws SqlException {
    createModelsAndRun(() -> {
        sink.clear();
        ExecutionModel model = compiler.testCompileModel(query, sqlExecutionContext);
        Assert.assertEquals(model.getModelType(), modelType);
        ((Sinkable) model).toSink(sink);
        if (model instanceof QueryModel) {
            validateTopDownColumns((QueryModel) model);
        }
        TestUtils.assertEquals(expected, sink);
    }, tableModels);
}
Also used : ExecutionModel(io.questdb.griffin.model.ExecutionModel) QueryModel(io.questdb.griffin.model.QueryModel)

Aggregations

QueryModel (io.questdb.griffin.model.QueryModel)7 EmptyTableRecordCursorFactory (io.questdb.griffin.engine.EmptyTableRecordCursorFactory)3 LimitRecordCursorFactory (io.questdb.griffin.engine.LimitRecordCursorFactory)3 CachedAnalyticRecordCursorFactory (io.questdb.griffin.engine.analytic.CachedAnalyticRecordCursorFactory)3 GroupByRecordCursorFactory (io.questdb.griffin.engine.groupby.vect.GroupByRecordCursorFactory)3 SortedLightRecordCursorFactory (io.questdb.griffin.engine.orderby.SortedLightRecordCursorFactory)3 SortedRecordCursorFactory (io.questdb.griffin.engine.orderby.SortedRecordCursorFactory)3 AnalyticFunction (io.questdb.griffin.engine.analytic.AnalyticFunction)2 GroupByFunction (io.questdb.griffin.engine.functions.GroupByFunction)2 SymbolFunction (io.questdb.griffin.engine.functions.SymbolFunction)2 QueryColumn (io.questdb.griffin.model.QueryColumn)2 ExecutionModel (io.questdb.griffin.model.ExecutionModel)1 ExpressionNode (io.questdb.griffin.model.ExpressionNode)1 Test (org.junit.Test)1