Search in sources :

Example 26 with VoltCompilerException

use of org.voltdb.compiler.VoltCompiler.VoltCompilerException in project voltdb by VoltDB.

the class DDLCompiler method loadSchema.

/**
     * Compile a DDL schema from an abstract reader
     * @param reader  abstract DDL reader
     * @param db  database
     * @param whichProcs  which type(s) of procedures to load
     * @throws VoltCompiler.VoltCompilerException
     */
void loadSchema(Reader reader, Database db, DdlProceduresToLoad whichProcs) throws VoltCompiler.VoltCompilerException {
    m_currLineNo = 1;
    DDLStatement stmt = getNextStatement(reader, m_compiler);
    while (stmt != null) {
        // Some statements are processed by VoltDB and the rest are handled by HSQL.
        processVoltDBStatements(db, whichProcs, stmt);
        stmt = getNextStatement(reader, m_compiler);
    }
    try {
        reader.close();
    } catch (IOException e) {
        throw m_compiler.new VoltCompilerException("Error closing schema file");
    }
    // process extra classes
    m_tracker.addExtraClasses(m_classMatcher.getMatchedClassList());
    // possibly save some memory
    m_classMatcher.clear();
}
Also used : IOException(java.io.IOException) VoltCompilerException(org.voltdb.compiler.VoltCompiler.VoltCompilerException)

Example 27 with VoltCompilerException

use of org.voltdb.compiler.VoltCompiler.VoltCompilerException in project voltdb by VoltDB.

the class DDLCompiler method processCreateStreamStatement.

/**
     * Process a VoltDB-specific create stream DDL statement
     *
     * @param stmt
     *            DDL statement string
     * @param db
     * @param whichProcs
     * @throws VoltCompilerException
     */
private void processCreateStreamStatement(DDLStatement stmt, Database db, DdlProceduresToLoad whichProcs) throws VoltCompilerException {
    String statement = stmt.statement;
    Matcher statementMatcher = SQLParser.matchCreateStream(statement);
    if (statementMatcher.matches()) {
        // check the table portion
        String tableName = checkIdentifierStart(statementMatcher.group(1), statement);
        String targetName = null;
        String columnName = null;
        // Parse the EXPORT and PARTITION clauses.
        if ((statementMatcher.groupCount() > 1) && (statementMatcher.group(2) != null) && (!statementMatcher.group(2).isEmpty())) {
            String clauses = statementMatcher.group(2);
            Matcher matcher = SQLParser.matchAnyCreateStreamStatementClause(clauses);
            int start = 0;
            while (matcher.find(start)) {
                start = matcher.end();
                if (matcher.group(1) != null) {
                    // Add target info if it's an Export clause. Only one is allowed
                    if (targetName != null) {
                        throw m_compiler.new VoltCompilerException("Only one Export clause is allowed for CREATE STREAM.");
                    }
                    targetName = matcher.group(1);
                } else {
                    // Add partition info if it's a PARTITION clause. Only one is allowed.
                    if (columnName != null) {
                        throw m_compiler.new VoltCompilerException("Only one PARTITION clause is allowed for CREATE STREAM.");
                    }
                    columnName = matcher.group(2);
                }
            }
        }
        VoltXMLElement tableXML = m_schema.findChild("table", tableName.toUpperCase());
        if (tableXML != null) {
            tableXML.attributes.put("stream", "true");
        } else {
            throw m_compiler.new VoltCompilerException(String.format("Invalid STREAM statement: table %s does not exist", tableName));
        }
        // process partition if specified
        if (columnName != null) {
            tableXML.attributes.put("partitioncolumn", columnName.toUpperCase());
            // Column validity check done by VoltCompiler in post-processing
            // mark the table as dirty for the purposes of caching sql statements
            m_compiler.markTableAsDirty(tableName);
        }
        // process export
        targetName = (targetName != null) ? checkIdentifierStart(targetName, statement) : Constants.DEFAULT_EXPORT_CONNECTOR_NAME;
        if (tableXML.attributes.containsKey("drTable") && "ENABLE".equals(tableXML.attributes.get("drTable"))) {
            throw m_compiler.new VoltCompilerException(String.format("Invalid CREATE STREAM statement: table %s is a DR table.", tableName));
        } else {
            tableXML.attributes.put("export", targetName);
        }
    } else {
        throw m_compiler.new VoltCompilerException(String.format("Invalid CREATE STREAM statement: \"%s\", " + "expected syntax: CREATE STREAM <table> [PARTITION ON COLUMN <column-name>] [EXPORT TO TARGET <target>] (column datatype, ...); ", statement.substring(0, statement.length() - 1)));
    }
}
Also used : Matcher(java.util.regex.Matcher) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement) VoltCompilerException(org.voltdb.compiler.VoltCompiler.VoltCompilerException) Constraint(org.voltdb.catalog.Constraint)

Example 28 with VoltCompilerException

use of org.voltdb.compiler.VoltCompiler.VoltCompilerException in project voltdb by VoltDB.

the class DDLCompiler method checkValidPartitionTableIndex.

private void checkValidPartitionTableIndex(Index index, Column partitionCol, String tableName) throws VoltCompilerException {
    // skip checking for non-unique indexes.
    if (!index.getUnique()) {
        return;
    }
    boolean containsPartitionColumn = false;
    String jsonExpr = index.getExpressionsjson();
    // if this is a pure-column index...
    if (jsonExpr.isEmpty()) {
        for (ColumnRef cref : index.getColumns()) {
            Column col = cref.getColumn();
            // unique index contains partitioned column
            if (col.equals(partitionCol)) {
                containsPartitionColumn = true;
                break;
            }
        }
    } else // if this is a fancy expression-based index...
    {
        try {
            int partitionColIndex = partitionCol.getIndex();
            List<AbstractExpression> indexExpressions = AbstractExpression.fromJSONArrayString(jsonExpr, null);
            for (AbstractExpression expr : indexExpressions) {
                if (expr instanceof TupleValueExpression && ((TupleValueExpression) expr).getColumnIndex() == partitionColIndex) {
                    containsPartitionColumn = true;
                    break;
                }
            }
        } catch (JSONException e) {
            // danger will robinson
            e.printStackTrace();
            assert (false);
        }
    }
    if (containsPartitionColumn) {
        if (index.getAssumeunique()) {
            String exceptionMsg = String.format("ASSUMEUNIQUE is not valid " + "for an index that includes the partitioning column. Please use UNIQUE instead.");
            throw m_compiler.new VoltCompilerException(exceptionMsg);
        }
    } else if (!index.getAssumeunique()) {
        // Throw compiler exception.
        String indexName = index.getTypeName();
        String keyword = "";
        if (indexName.startsWith(HSQLInterface.AUTO_GEN_PRIMARY_KEY_PREFIX)) {
            indexName = "PRIMARY KEY";
            keyword = "PRIMARY KEY";
        } else {
            indexName = "UNIQUE INDEX " + indexName;
            keyword = "UNIQUE";
        }
        String exceptionMsg = "Invalid use of " + keyword + ". The " + indexName + " on the partitioned table " + tableName + " does not include the partitioning column " + partitionCol.getName() + ". See the documentation for the 'CREATE TABLE' and 'CREATE INDEX' commands and the 'ASSUMEUNIQUE' keyword.";
        throw m_compiler.new VoltCompilerException(exceptionMsg);
    }
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression) Column(org.voltdb.catalog.Column) JSONException(org.json_voltpatches.JSONException) ColumnRef(org.voltdb.catalog.ColumnRef) VoltCompilerException(org.voltdb.compiler.VoltCompiler.VoltCompilerException) Constraint(org.voltdb.catalog.Constraint)

Example 29 with VoltCompilerException

use of org.voltdb.compiler.VoltCompiler.VoltCompilerException in project voltdb by VoltDB.

the class DDLCompiler method handlePartitions.

void handlePartitions(Database db) throws VoltCompilerException {
    // Actually parse and handle all the partitions
    // this needs to happen before procedures are compiled
    String msg = "In database, ";
    final CatalogMap<Table> tables = db.getTables();
    for (Table table : tables) {
        String tableName = table.getTypeName();
        if (m_tracker.m_partitionMap.containsKey(tableName.toLowerCase())) {
            String colName = m_tracker.m_partitionMap.get(tableName.toLowerCase());
            // because it defaults to replicated in the catalog.
            if (colName != null) {
                assert (tables.getIgnoreCase(tableName) != null);
                if (m_matViewMap.containsKey(table)) {
                    msg += "the materialized view is automatically partitioned based on its source table. " + "Invalid PARTITION statement on view table " + tableName + ".";
                    throw m_compiler.new VoltCompilerException(msg);
                }
                final Column partitionCol = table.getColumns().getIgnoreCase(colName);
                // make sure the column exists
                if (partitionCol == null) {
                    msg += "PARTITION has unknown COLUMN '" + colName + "'";
                    throw m_compiler.new VoltCompilerException(msg);
                }
                // make sure the column is marked not-nullable
                if (partitionCol.getNullable() == true) {
                    msg += "Partition column '" + tableName + "." + colName + "' is nullable. " + "Partition columns must be constrained \"NOT NULL\".";
                    throw m_compiler.new VoltCompilerException(msg);
                }
                // verify that the partition column is a supported type
                VoltType pcolType = VoltType.get((byte) partitionCol.getType());
                switch(pcolType) {
                    case TINYINT:
                    case SMALLINT:
                    case INTEGER:
                    case BIGINT:
                    case STRING:
                    case VARBINARY:
                        break;
                    default:
                        msg += "Partition column '" + tableName + "." + colName + "' is not a valid type. " + "Partition columns must be an integer, varchar or varbinary type.";
                        throw m_compiler.new VoltCompilerException(msg);
                }
                table.setPartitioncolumn(partitionCol);
                table.setIsreplicated(false);
                // Check valid indexes, whether they contain the partition column or not.
                for (Index index : table.getIndexes()) {
                    checkValidPartitionTableIndex(index, partitionCol, tableName);
                }
            }
        }
    }
}
Also used : DRTable(org.voltdb.compiler.statements.DRTable) Table(org.voltdb.catalog.Table) ReplicateTable(org.voltdb.compiler.statements.ReplicateTable) Column(org.voltdb.catalog.Column) VoltType(org.voltdb.VoltType) Index(org.voltdb.catalog.Index) VoltCompilerException(org.voltdb.compiler.VoltCompiler.VoltCompilerException)

Example 30 with VoltCompilerException

use of org.voltdb.compiler.VoltCompiler.VoltCompilerException in project voltdb by VoltDB.

the class DDLCompiler method addColumnToCatalog.

private static void addColumnToCatalog(Table table, VoltXMLElement node, SortedMap<Integer, VoltType> columnTypes, Map<String, Column> columnMap, VoltCompiler compiler) throws VoltCompilerException {
    assert node.name.equals("column");
    String name = node.attributes.get("name");
    String typename = node.attributes.get("valuetype");
    String nullable = node.attributes.get("nullable");
    String sizeString = node.attributes.get("size");
    int index = Integer.valueOf(node.attributes.get("index"));
    String defaultvalue = null;
    String defaulttype = null;
    int defaultFuncID = -1;
    // Default Value
    for (VoltXMLElement child : node.children) {
        if (child.name.equals("default")) {
            for (VoltXMLElement inner_child : child.children) {
                // Value
                if (inner_child.name.equals("value")) {
                    // There should be only one default value/type.
                    assert (defaulttype == null);
                    defaultvalue = inner_child.attributes.get("value");
                    defaulttype = inner_child.attributes.get("valuetype");
                    assert (defaulttype != null);
                } else if (inner_child.name.equals("function")) {
                    // There should be only one default value/type.
                    assert (defaulttype == null);
                    defaultFuncID = Integer.parseInt(inner_child.attributes.get("function_id"));
                    defaultvalue = inner_child.attributes.get("name");
                    defaulttype = inner_child.attributes.get("valuetype");
                    assert (defaulttype != null);
                }
            }
        }
    }
    if (defaulttype != null) {
        // fyi: Historically, VoltType class initialization errors get reported on this line (?).
        defaulttype = Integer.toString(VoltType.typeFromString(defaulttype).getValue());
    }
    // replace newlines in default values
    if (defaultvalue != null) {
        defaultvalue = defaultvalue.replace('\n', ' ');
        defaultvalue = defaultvalue.replace('\r', ' ');
    }
    // fyi: Historically, VoltType class initialization errors get reported on this line (?).
    VoltType type = VoltType.typeFromString(typename);
    columnTypes.put(index, type);
    if (defaultFuncID == -1) {
        if (defaultvalue != null && (type == VoltType.DECIMAL || type == VoltType.NUMERIC)) {
            // Until we support deserializing scientific notation in the EE, we'll
            // coerce default values to plain notation here.  See ENG-952 for more info.
            BigDecimal temp = new BigDecimal(defaultvalue);
            defaultvalue = temp.toPlainString();
        }
    } else {
        // Concat function name and function id, format: NAME:ID
        // Used by PlanAssembler:getNextInsertPlan().
        defaultvalue = defaultvalue + ":" + String.valueOf(defaultFuncID);
    }
    Column column = table.getColumns().add(name);
    // need to set other column data here (default, nullable, etc)
    column.setName(name);
    column.setIndex(index);
    column.setType(type.getValue());
    column.setNullable(Boolean.valueOf(nullable));
    int size = type.getMaxLengthInBytes();
    boolean inBytes = false;
    if (node.attributes.containsKey("bytes")) {
        inBytes = Boolean.valueOf(node.attributes.get("bytes"));
    }
    // Determine the length of columns with a variable-length type
    if (type.isVariableLength()) {
        int userSpecifiedSize = 0;
        if (sizeString != null) {
            userSpecifiedSize = Integer.parseInt(sizeString);
        }
        if (userSpecifiedSize == 0) {
            // So size specified in the column definition.  Either:
            // - the user-specified size is zero (unclear how this would happen---
            //   if someone types VARCHAR(0) HSQL will complain)
            // - or the sizeString was null, meaning that the size specifier was
            //   omitted.
            // Choose an appropriate default for the type.
            size = type.defaultLengthForVariableLengthType();
        } else {
            if (userSpecifiedSize < 0 || (inBytes && userSpecifiedSize > VoltType.MAX_VALUE_LENGTH)) {
                String msg = type.toSQLString() + " column " + name + " in table " + table.getTypeName() + " has unsupported length " + sizeString;
                throw compiler.new VoltCompilerException(msg);
            }
            if (!inBytes && type == VoltType.STRING) {
                if (userSpecifiedSize > VoltType.MAX_VALUE_LENGTH_IN_CHARACTERS) {
                    String msg = String.format("The size of VARCHAR column %s in table %s greater than %d " + "will be enforced as byte counts rather than UTF8 character counts. " + "To eliminate this warning, specify \"VARCHAR(%d BYTES)\"", name, table.getTypeName(), VoltType.MAX_VALUE_LENGTH_IN_CHARACTERS, userSpecifiedSize);
                    compiler.addWarn(msg);
                    inBytes = true;
                }
            }
            if (userSpecifiedSize < type.getMinLengthInBytes()) {
                String msg = type.toSQLString() + " column " + name + " in table " + table.getTypeName() + " has length of " + sizeString + " which is shorter than " + type.getMinLengthInBytes() + ", " + "the minimum allowed length for the type.";
                throw compiler.new VoltCompilerException(msg);
            }
            size = userSpecifiedSize;
        }
    }
    column.setInbytes(inBytes);
    column.setSize(size);
    column.setDefaultvalue(defaultvalue);
    if (defaulttype != null)
        column.setDefaulttype(Integer.parseInt(defaulttype));
    columnMap.put(name, column);
}
Also used : VoltType(org.voltdb.VoltType) Column(org.voltdb.catalog.Column) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement) VoltCompilerException(org.voltdb.compiler.VoltCompiler.VoltCompilerException) Constraint(org.voltdb.catalog.Constraint) BigDecimal(java.math.BigDecimal)

Aggregations

VoltCompilerException (org.voltdb.compiler.VoltCompiler.VoltCompilerException)38 Matcher (java.util.regex.Matcher)15 Constraint (org.voltdb.catalog.Constraint)11 VoltXMLElement (org.hsqldb_voltpatches.VoltXMLElement)10 Column (org.voltdb.catalog.Column)7 AbstractExpression (org.voltdb.expressions.AbstractExpression)7 VoltType (org.voltdb.VoltType)6 Index (org.voltdb.catalog.Index)5 IOException (java.io.IOException)4 HSQLParseException (org.hsqldb_voltpatches.HSQLInterface.HSQLParseException)4 JSONException (org.json_voltpatches.JSONException)4 VoltTypeException (org.voltdb.VoltTypeException)4 Group (org.voltdb.catalog.Group)4 ProcParameter (org.voltdb.catalog.ProcParameter)4 Statement (org.voltdb.catalog.Statement)4 Table (org.voltdb.catalog.Table)4 Method (java.lang.reflect.Method)3 ArrayList (java.util.ArrayList)3 ColumnRef (org.voltdb.catalog.ColumnRef)3 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)3