Search in sources :

Example 1 with ExpressionCompiler

use of org.apache.phoenix.compile.ExpressionCompiler in project phoenix by apache.

the class ColumnRef method newColumnExpression.

public Expression newColumnExpression(boolean schemaNameCaseSensitive, boolean colNameCaseSensitive) throws SQLException {
    PTable table = tableRef.getTable();
    PColumn column = this.getColumn();
    String displayName = tableRef.getColumnDisplayName(this, schemaNameCaseSensitive, colNameCaseSensitive);
    if (SchemaUtil.isPKColumn(column)) {
        return new RowKeyColumnExpression(column, new RowKeyValueAccessor(table.getPKColumns(), pkSlotPosition), displayName);
    }
    if (table.getType() == PTableType.PROJECTED || table.getType() == PTableType.SUBQUERY) {
        return new ProjectedColumnExpression(column, table, displayName);
    }
    Expression expression = table.getImmutableStorageScheme() == ImmutableStorageScheme.SINGLE_CELL_ARRAY_WITH_OFFSETS ? new SingleCellColumnExpression(column, displayName, table.getEncodingScheme()) : new KeyValueColumnExpression(column, displayName);
    if (column.getExpressionStr() != null) {
        String url = PhoenixRuntime.JDBC_PROTOCOL + PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + PhoenixRuntime.CONNECTIONLESS;
        PhoenixConnection conn = DriverManager.getConnection(url).unwrap(PhoenixConnection.class);
        StatementContext context = new StatementContext(new PhoenixStatement(conn));
        ExpressionCompiler compiler = new ExpressionCompiler(context);
        ParseNode defaultParseNode = new SQLParser(column.getExpressionStr()).parseExpression();
        Expression defaultExpression = defaultParseNode.accept(compiler);
        if (!ExpressionUtil.isNull(defaultExpression, new ImmutableBytesWritable())) {
            return new DefaultValueExpression(Arrays.asList(expression, defaultExpression));
        }
    }
    return expression;
}
Also used : PhoenixConnection(org.apache.phoenix.jdbc.PhoenixConnection) ImmutableBytesWritable(org.apache.hadoop.hbase.io.ImmutableBytesWritable) ProjectedColumnExpression(org.apache.phoenix.expression.ProjectedColumnExpression) RowKeyColumnExpression(org.apache.phoenix.expression.RowKeyColumnExpression) PhoenixStatement(org.apache.phoenix.jdbc.PhoenixStatement) StatementContext(org.apache.phoenix.compile.StatementContext) SingleCellColumnExpression(org.apache.phoenix.expression.SingleCellColumnExpression) KeyValueColumnExpression(org.apache.phoenix.expression.KeyValueColumnExpression) Expression(org.apache.phoenix.expression.Expression) SingleCellColumnExpression(org.apache.phoenix.expression.SingleCellColumnExpression) ProjectedColumnExpression(org.apache.phoenix.expression.ProjectedColumnExpression) RowKeyColumnExpression(org.apache.phoenix.expression.RowKeyColumnExpression) DefaultValueExpression(org.apache.phoenix.expression.function.DefaultValueExpression) SQLParser(org.apache.phoenix.parse.SQLParser) ParseNode(org.apache.phoenix.parse.ParseNode) ExpressionCompiler(org.apache.phoenix.compile.ExpressionCompiler) KeyValueColumnExpression(org.apache.phoenix.expression.KeyValueColumnExpression) DefaultValueExpression(org.apache.phoenix.expression.function.DefaultValueExpression)

Example 2 with ExpressionCompiler

use of org.apache.phoenix.compile.ExpressionCompiler in project phoenix by apache.

the class ColumnDef method validateDefault.

public boolean validateDefault(StatementContext context, PrimaryKeyConstraint pkConstraint) throws SQLException {
    String defaultStr = this.getExpression();
    if (defaultStr == null) {
        return true;
    }
    ExpressionCompiler compiler = new ExpressionCompiler(context);
    ParseNode defaultParseNode = new SQLParser(this.getExpression()).parseExpression();
    Expression defaultExpression = defaultParseNode.accept(compiler);
    if (!defaultParseNode.isStateless() || defaultExpression.getDeterminism() != Determinism.ALWAYS) {
        throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_CREATE_DEFAULT).setColumnName(this.getColumnDefName().getColumnName()).build().buildException();
    }
    if (this.isRowTimestamp() || (pkConstraint != null && pkConstraint.isColumnRowTimestamp(this.getColumnDefName()))) {
        throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_CREATE_DEFAULT_ROWTIMESTAMP).setColumnName(this.getColumnDefName().getColumnName()).build().buildException();
    }
    ImmutableBytesWritable ptr = new ImmutableBytesWritable();
    // Evaluate the expression to confirm it's validity
    LiteralExpression defaultValue = ExpressionUtil.getConstantExpression(defaultExpression, ptr);
    // A DEFAULT that evaluates to null should be ignored as it adds nothing
    if (defaultValue.getValue() == null) {
        return false;
    }
    PDataType sourceType = defaultExpression.getDataType();
    PDataType targetType = this.getDataType();
    // Ensure that coercion works (will throw if not)
    context.getTempPtr().set(ptr.get(), ptr.getOffset(), ptr.getLength());
    try {
        targetType.coerceBytes(context.getTempPtr(), defaultValue.getValue(), sourceType, defaultValue.getMaxLength(), defaultValue.getScale(), defaultValue.getSortOrder(), this.getMaxLength(), this.getScale(), this.getSortOrder());
    } catch (ConstraintViolationException e) {
        if (e.getCause() instanceof SQLException) {
            SQLException sqlE = (SQLException) e.getCause();
            throw new DelegateSQLException(sqlE, ". DEFAULT " + SQLExceptionInfo.COLUMN_NAME + "=" + this.getColumnDefName().getColumnName());
        }
        throw e;
    }
    if (!targetType.isSizeCompatible(ptr, defaultValue.getValue(), sourceType, sortOrder, defaultValue.getMaxLength(), defaultValue.getScale(), this.getMaxLength(), this.getScale())) {
        throw new SQLExceptionInfo.Builder(SQLExceptionCode.DATA_EXCEEDS_MAX_CAPACITY).setColumnName(this.getColumnDefName().getColumnName()).setMessage("DEFAULT " + this.getExpression()).build().buildException();
    }
    return true;
}
Also used : ImmutableBytesWritable(org.apache.hadoop.hbase.io.ImmutableBytesWritable) SQLException(java.sql.SQLException) DelegateSQLException(org.apache.phoenix.schema.DelegateSQLException) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) DelegateSQLException(org.apache.phoenix.schema.DelegateSQLException) PDataType(org.apache.phoenix.schema.types.PDataType) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) Expression(org.apache.phoenix.expression.Expression) ConstraintViolationException(org.apache.phoenix.schema.ConstraintViolationException) ExpressionCompiler(org.apache.phoenix.compile.ExpressionCompiler) SQLExceptionInfo(org.apache.phoenix.exception.SQLExceptionInfo)

Example 3 with ExpressionCompiler

use of org.apache.phoenix.compile.ExpressionCompiler in project phoenix by apache.

the class PTableImpl method newKey.

@Override
public int newKey(ImmutableBytesWritable key, byte[][] values) {
    List<PColumn> columns = getPKColumns();
    int nValues = values.length;
    while (nValues > 0 && (values[nValues - 1] == null || values[nValues - 1].length == 0)) {
        nValues--;
    }
    for (PColumn column : columns) {
        if (column.getExpressionStr() != null) {
            nValues++;
        }
    }
    int i = 0;
    TrustedByteArrayOutputStream os = new TrustedByteArrayOutputStream(SchemaUtil.estimateKeyLength(this));
    try {
        Integer bucketNum = this.getBucketNum();
        if (bucketNum != null) {
            // Write place holder for salt byte
            i++;
            os.write(QueryConstants.SEPARATOR_BYTE_ARRAY);
        }
        int nColumns = columns.size();
        PDataType type = null;
        SortOrder sortOrder = null;
        boolean wasNull = false;
        while (i < nValues && i < nColumns) {
            // Separate variable length column values in key with zero byte
            if (type != null && !type.isFixedWidth()) {
                os.write(SchemaUtil.getSeparatorByte(rowKeyOrderOptimizable(), wasNull, sortOrder));
            }
            PColumn column = columns.get(i);
            sortOrder = column.getSortOrder();
            type = column.getDataType();
            // This will throw if the value is null and the type doesn't allow null
            byte[] byteValue = values[i++];
            if (byteValue == null) {
                if (column.getExpressionStr() != null) {
                    try {
                        String url = PhoenixRuntime.JDBC_PROTOCOL + PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + PhoenixRuntime.CONNECTIONLESS;
                        PhoenixConnection conn = DriverManager.getConnection(url).unwrap(PhoenixConnection.class);
                        StatementContext context = new StatementContext(new PhoenixStatement(conn));
                        ExpressionCompiler compiler = new ExpressionCompiler(context);
                        ParseNode defaultParseNode = new SQLParser(column.getExpressionStr()).parseExpression();
                        Expression defaultExpression = defaultParseNode.accept(compiler);
                        defaultExpression.evaluate(null, key);
                        column.getDataType().coerceBytes(key, null, defaultExpression.getDataType(), defaultExpression.getMaxLength(), defaultExpression.getScale(), defaultExpression.getSortOrder(), column.getMaxLength(), column.getScale(), column.getSortOrder());
                        byteValue = ByteUtil.copyKeyBytesIfNecessary(key);
                    } catch (SQLException e) {
                        // should not be possible
                        throw new ConstraintViolationException(name.getString() + "." + column.getName().getString() + " failed to compile default value expression of " + column.getExpressionStr());
                    }
                } else {
                    byteValue = ByteUtil.EMPTY_BYTE_ARRAY;
                }
            }
            wasNull = byteValue.length == 0;
            // here.
            if (byteValue.length == 0 && !column.isNullable()) {
                throw new ConstraintViolationException(name.getString() + "." + column.getName().getString() + " may not be null");
            }
            Integer maxLength = column.getMaxLength();
            Integer scale = column.getScale();
            key.set(byteValue);
            if (!type.isSizeCompatible(key, null, type, sortOrder, null, null, maxLength, scale)) {
                throw new DataExceedsCapacityException(name.getString() + "." + column.getName().getString() + " may not exceed " + maxLength + " (" + SchemaUtil.toString(type, byteValue) + ")");
            }
            key.set(byteValue);
            type.pad(key, maxLength, sortOrder);
            byteValue = ByteUtil.copyKeyBytesIfNecessary(key);
            os.write(byteValue, 0, byteValue.length);
        }
        // Need trailing byte for DESC columns
        if (type != null && !type.isFixedWidth() && SchemaUtil.getSeparatorByte(rowKeyOrderOptimizable(), wasNull, sortOrder) == QueryConstants.DESC_SEPARATOR_BYTE) {
            os.write(QueryConstants.DESC_SEPARATOR_BYTE);
        }
        // If some non null pk values aren't set, then throw
        if (i < nColumns) {
            PColumn column = columns.get(i);
            if (column.getDataType().isFixedWidth() || !column.isNullable()) {
                throw new ConstraintViolationException(name.getString() + "." + column.getName().getString() + " may not be null");
            }
        }
        if (nValues == 0) {
            throw new ConstraintViolationException("Primary key may not be null (" + name.getString() + ")");
        }
        byte[] buf = os.getBuffer();
        int size = os.size();
        if (bucketNum != null) {
            buf[0] = SaltingUtil.getSaltingByte(buf, 1, size - 1, bucketNum);
        }
        key.set(buf, 0, size);
        return i;
    } finally {
        try {
            os.close();
        } catch (IOException e) {
            // Impossible
            throw new RuntimeException(e);
        }
    }
}
Also used : PhoenixConnection(org.apache.phoenix.jdbc.PhoenixConnection) SQLException(java.sql.SQLException) TrustedByteArrayOutputStream(org.apache.phoenix.util.TrustedByteArrayOutputStream) IOException(java.io.IOException) PhoenixStatement(org.apache.phoenix.jdbc.PhoenixStatement) StatementContext(org.apache.phoenix.compile.StatementContext) DataExceedsCapacityException(org.apache.phoenix.exception.DataExceedsCapacityException) PDataType(org.apache.phoenix.schema.types.PDataType) SQLParser(org.apache.phoenix.parse.SQLParser) SingleCellConstructorExpression(org.apache.phoenix.expression.SingleCellConstructorExpression) Expression(org.apache.phoenix.expression.Expression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) ParseNode(org.apache.phoenix.parse.ParseNode) ExpressionCompiler(org.apache.phoenix.compile.ExpressionCompiler)

Aggregations

ExpressionCompiler (org.apache.phoenix.compile.ExpressionCompiler)3 Expression (org.apache.phoenix.expression.Expression)3 SQLException (java.sql.SQLException)2 ImmutableBytesWritable (org.apache.hadoop.hbase.io.ImmutableBytesWritable)2 StatementContext (org.apache.phoenix.compile.StatementContext)2 LiteralExpression (org.apache.phoenix.expression.LiteralExpression)2 PhoenixConnection (org.apache.phoenix.jdbc.PhoenixConnection)2 PhoenixStatement (org.apache.phoenix.jdbc.PhoenixStatement)2 ParseNode (org.apache.phoenix.parse.ParseNode)2 SQLParser (org.apache.phoenix.parse.SQLParser)2 PDataType (org.apache.phoenix.schema.types.PDataType)2 IOException (java.io.IOException)1 DataExceedsCapacityException (org.apache.phoenix.exception.DataExceedsCapacityException)1 SQLExceptionInfo (org.apache.phoenix.exception.SQLExceptionInfo)1 KeyValueColumnExpression (org.apache.phoenix.expression.KeyValueColumnExpression)1 ProjectedColumnExpression (org.apache.phoenix.expression.ProjectedColumnExpression)1 RowKeyColumnExpression (org.apache.phoenix.expression.RowKeyColumnExpression)1 SingleCellColumnExpression (org.apache.phoenix.expression.SingleCellColumnExpression)1 SingleCellConstructorExpression (org.apache.phoenix.expression.SingleCellConstructorExpression)1 DefaultValueExpression (org.apache.phoenix.expression.function.DefaultValueExpression)1