Search in sources :

Example 1 with ExtTypeInfoRow

use of org.h2.value.ExtTypeInfoRow in project h2database by h2database.

the class Aggregate method optimize.

@Override
public Expression optimize(SessionLocal session) {
    super.optimize(session);
    if (args.length == 1) {
        type = args[0].getType();
    }
    if (orderByList != null) {
        int offset;
        switch(aggregateType) {
            case ARRAY_AGG:
            case LISTAGG:
            case JSON_ARRAYAGG:
                offset = 1;
                break;
            default:
                offset = 0;
        }
        for (Iterator<QueryOrderBy> i = orderByList.iterator(); i.hasNext(); ) {
            QueryOrderBy o = i.next();
            Expression e = o.expression.optimize(session);
            if (offset != 0 && e.isConstant()) {
                i.remove();
            } else {
                o.expression = e;
            }
        }
        if (orderByList.isEmpty()) {
            orderByList = null;
        } else {
            orderBySort = createOrder(session, orderByList, offset);
        }
    }
    switch(aggregateType) {
        case LISTAGG:
            type = TypeInfo.TYPE_VARCHAR;
            break;
        case COUNT:
            if (args[0].isConstant()) {
                if (args[0].getValue(session) == ValueNull.INSTANCE) {
                    return ValueExpression.get(ValueBigint.get(0L));
                }
                if (!distinct) {
                    Aggregate aggregate = new Aggregate(AggregateType.COUNT_ALL, new Expression[0], select, false);
                    aggregate.setFilterCondition(filterCondition);
                    aggregate.setOverCondition(over);
                    return aggregate.optimize(session);
                }
            }
        // $FALL-THROUGH$
        case COUNT_ALL:
        case REGR_COUNT:
            type = TypeInfo.TYPE_BIGINT;
            break;
        case HISTOGRAM:
            {
                LinkedHashMap<String, TypeInfo> fields = new LinkedHashMap<>(4);
                fields.put("VALUE", type);
                fields.put("COUNT", TypeInfo.TYPE_BIGINT);
                type = TypeInfo.getTypeInfo(Value.ARRAY, -1, 0, TypeInfo.getTypeInfo(Value.ROW, -1, -1, new ExtTypeInfoRow(fields)));
                break;
            }
        case SUM:
            if ((type = getSumType(type)) == null) {
                throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getTraceSQL());
            }
            break;
        case AVG:
            if ((type = getAvgType(type)) == null) {
                throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getTraceSQL());
            }
            break;
        case MIN:
        case MAX:
            break;
        case STDDEV_POP:
        case STDDEV_SAMP:
        case VAR_POP:
        case VAR_SAMP:
        case COVAR_POP:
        case COVAR_SAMP:
        case CORR:
        case REGR_SLOPE:
        case REGR_INTERCEPT:
        case REGR_R2:
        case REGR_SXX:
        case REGR_SYY:
        case REGR_SXY:
            type = TypeInfo.TYPE_DOUBLE;
            break;
        case REGR_AVGX:
            if ((type = getAvgType(args[1].getType())) == null) {
                throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getTraceSQL());
            }
            break;
        case REGR_AVGY:
            if ((type = getAvgType(args[0].getType())) == null) {
                throw DbException.get(ErrorCode.SUM_OR_AVG_ON_WRONG_DATATYPE_1, getTraceSQL());
            }
            break;
        case RANK:
        case DENSE_RANK:
            type = TypeInfo.TYPE_BIGINT;
            break;
        case PERCENT_RANK:
        case CUME_DIST:
            type = TypeInfo.TYPE_DOUBLE;
            break;
        case PERCENTILE_CONT:
            type = orderByList.get(0).expression.getType();
        // $FALL-THROUGH$
        case MEDIAN:
            switch(type.getValueType()) {
                case Value.TINYINT:
                case Value.SMALLINT:
                case Value.INTEGER:
                case Value.BIGINT:
                case Value.NUMERIC:
                case Value.REAL:
                case Value.DOUBLE:
                case Value.DECFLOAT:
                    type = TypeInfo.TYPE_NUMERIC_FLOATING_POINT;
                    break;
            }
            break;
        case PERCENTILE_DISC:
        case MODE:
            type = orderByList.get(0).expression.getType();
            break;
        case EVERY:
        case ANY:
            type = TypeInfo.TYPE_BOOLEAN;
            break;
        case BIT_AND_AGG:
        case BIT_OR_AGG:
        case BIT_XOR_AGG:
        case BIT_NAND_AGG:
        case BIT_NOR_AGG:
        case BIT_XNOR_AGG:
            BitFunction.checkArgType(args[0]);
            break;
        case ARRAY_AGG:
            type = TypeInfo.getTypeInfo(Value.ARRAY, -1, 0, args[0].getType());
            break;
        case ENVELOPE:
            type = TypeInfo.TYPE_GEOMETRY;
            break;
        case JSON_OBJECTAGG:
        case JSON_ARRAYAGG:
            type = TypeInfo.TYPE_JSON;
            break;
        default:
            throw DbException.getInternalError("type=" + aggregateType);
    }
    return this;
}
Also used : ValueExpression(org.h2.expression.ValueExpression) Expression(org.h2.expression.Expression) ExtTypeInfoRow(org.h2.value.ExtTypeInfoRow) QueryOrderBy(org.h2.command.query.QueryOrderBy) ValueBigint(org.h2.value.ValueBigint) LinkedHashMap(java.util.LinkedHashMap)

Example 2 with ExtTypeInfoRow

use of org.h2.value.ExtTypeInfoRow in project h2database by h2database.

the class ValueDataType method readValue.

/**
 * Read a value.
 *
 * @param buff the source buffer
 * @param columnType the data type of value, or {@code null}
 * @return the value
 */
Value readValue(ByteBuffer buff, TypeInfo columnType) {
    int type = buff.get() & 255;
    switch(type) {
        case NULL:
            return ValueNull.INSTANCE;
        case BOOLEAN_TRUE:
            return ValueBoolean.TRUE;
        case BOOLEAN_FALSE:
            return ValueBoolean.FALSE;
        case INT_NEG:
            return ValueInteger.get(-readVarInt(buff));
        case INTEGER:
            return ValueInteger.get(readVarInt(buff));
        case BIGINT_NEG:
            return ValueBigint.get(-readVarLong(buff));
        case BIGINT:
            return ValueBigint.get(readVarLong(buff));
        case TINYINT:
            return ValueTinyint.get(buff.get());
        case SMALLINT:
            return ValueSmallint.get(buff.getShort());
        case NUMERIC_0_1:
            return ValueNumeric.ZERO;
        case NUMERIC_0_1 + 1:
            return ValueNumeric.ONE;
        case NUMERIC_SMALL_0:
            return ValueNumeric.get(BigDecimal.valueOf(readVarLong(buff)));
        case NUMERIC_SMALL:
            {
                int scale = readVarInt(buff);
                return ValueNumeric.get(BigDecimal.valueOf(readVarLong(buff), scale));
            }
        case NUMERIC:
            {
                int scale = readVarInt(buff);
                return ValueNumeric.get(new BigDecimal(new BigInteger(readVarBytes(buff)), scale));
            }
        case DECFLOAT:
            {
                int scale = readVarInt(buff), len = readVarInt(buff);
                switch(len) {
                    case -3:
                        return ValueDecfloat.NEGATIVE_INFINITY;
                    case -2:
                        return ValueDecfloat.POSITIVE_INFINITY;
                    case -1:
                        return ValueDecfloat.NAN;
                    default:
                        byte[] b = Utils.newBytes(len);
                        buff.get(b, 0, len);
                        return ValueDecfloat.get(new BigDecimal(new BigInteger(b), scale));
                }
            }
        case DATE:
            return ValueDate.fromDateValue(readVarLong(buff));
        case TIME:
            return ValueTime.fromNanos(readTimestampTime(buff));
        case TIME_TZ:
            return ValueTimeTimeZone.fromNanos(readVarInt(buff) * DateTimeUtils.NANOS_PER_SECOND + readVarInt(buff), readTimeZone(buff));
        case TIMESTAMP:
            return ValueTimestamp.fromDateValueAndNanos(readVarLong(buff), readTimestampTime(buff));
        case TIMESTAMP_TZ_OLD:
            return ValueTimestampTimeZone.fromDateValueAndNanos(readVarLong(buff), readTimestampTime(buff), readVarInt(buff) * 60);
        case TIMESTAMP_TZ:
            return ValueTimestampTimeZone.fromDateValueAndNanos(readVarLong(buff), readTimestampTime(buff), readTimeZone(buff));
        case VARBINARY:
            return ValueVarbinary.getNoCopy(readVarBytes(buff));
        case BINARY:
            return ValueBinary.getNoCopy(readVarBytes(buff));
        case JAVA_OBJECT:
            return ValueJavaObject.getNoCopy(readVarBytes(buff));
        case UUID:
            return ValueUuid.get(buff.getLong(), buff.getLong());
        case VARCHAR:
            return ValueVarchar.get(readString(buff));
        case VARCHAR_IGNORECASE:
            return ValueVarcharIgnoreCase.get(readString(buff));
        case CHAR:
            return ValueChar.get(readString(buff));
        case ENUM:
            {
                int ordinal = readVarInt(buff);
                if (columnType != null) {
                    return ((ExtTypeInfoEnum) columnType.getExtTypeInfo()).getValue(ordinal, provider);
                }
                return ValueInteger.get(ordinal);
            }
        case INTERVAL:
            {
                int ordinal = buff.get();
                boolean negative = ordinal < 0;
                if (negative) {
                    ordinal = ~ordinal;
                }
                return ValueInterval.from(IntervalQualifier.valueOf(ordinal), negative, readVarLong(buff), ordinal < 5 ? 0 : readVarLong(buff));
            }
        case REAL_0_1:
            return ValueReal.ZERO;
        case REAL_0_1 + 1:
            return ValueReal.ONE;
        case DOUBLE_0_1:
            return ValueDouble.ZERO;
        case DOUBLE_0_1 + 1:
            return ValueDouble.ONE;
        case DOUBLE:
            return ValueDouble.get(Double.longBitsToDouble(Long.reverse(readVarLong(buff))));
        case REAL:
            return ValueReal.get(Float.intBitsToFloat(Integer.reverse(readVarInt(buff))));
        case BLOB:
            {
                int smallLen = readVarInt(buff);
                if (smallLen >= 0) {
                    byte[] small = Utils.newBytes(smallLen);
                    buff.get(small, 0, smallLen);
                    return ValueBlob.createSmall(small);
                } else if (smallLen == -3) {
                    return new ValueBlob(readLobDataDatabase(buff), readVarLong(buff));
                } else {
                    throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "lob type: " + smallLen);
                }
            }
        case CLOB:
            {
                int smallLen = readVarInt(buff);
                if (smallLen >= 0) {
                    byte[] small = Utils.newBytes(smallLen);
                    buff.get(small, 0, smallLen);
                    return ValueClob.createSmall(small, readVarLong(buff));
                } else if (smallLen == -3) {
                    return new ValueClob(readLobDataDatabase(buff), readVarLong(buff), readVarLong(buff));
                } else {
                    throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "lob type: " + smallLen);
                }
            }
        case ARRAY:
            {
                if (columnType != null) {
                    TypeInfo elementType = (TypeInfo) columnType.getExtTypeInfo();
                    return ValueArray.get(elementType, readArrayElements(buff, elementType), provider);
                }
                return ValueArray.get(readArrayElements(buff, null), provider);
            }
        case ROW:
            {
                int len = readVarInt(buff);
                Value[] list = new Value[len];
                if (columnType != null) {
                    ExtTypeInfoRow extTypeInfoRow = (ExtTypeInfoRow) columnType.getExtTypeInfo();
                    Iterator<Entry<String, TypeInfo>> fields = extTypeInfoRow.getFields().iterator();
                    for (int i = 0; i < len; i++) {
                        list[i] = readValue(buff, fields.next().getValue());
                    }
                    return ValueRow.get(columnType, list);
                }
                TypeInfo[] columnTypes = rowFactory.getColumnTypes();
                for (int i = 0; i < len; i++) {
                    list[i] = readValue(buff, columnTypes[i]);
                }
                return ValueRow.get(list);
            }
        case GEOMETRY:
            return ValueGeometry.get(readVarBytes(buff));
        case JSON:
            return ValueJson.getInternal(readVarBytes(buff));
        default:
            if (type >= INT_0_15 && type < INT_0_15 + 16) {
                int i = type - INT_0_15;
                if (columnType != null && columnType.getValueType() == Value.ENUM) {
                    return ((ExtTypeInfoEnum) columnType.getExtTypeInfo()).getValue(i, provider);
                }
                return ValueInteger.get(i);
            } else if (type >= BIGINT_0_7 && type < BIGINT_0_7 + 8) {
                return ValueBigint.get(type - BIGINT_0_7);
            } else if (type >= VARBINARY_0_31 && type < VARBINARY_0_31 + 32) {
                int len = type - VARBINARY_0_31;
                byte[] b = Utils.newBytes(len);
                buff.get(b, 0, len);
                return ValueVarbinary.getNoCopy(b);
            } else if (type >= VARCHAR_0_31 && type < VARCHAR_0_31 + 32) {
                return ValueVarchar.get(readString(buff, type - VARCHAR_0_31));
            }
            throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "type: " + type);
    }
}
Also used : ExtTypeInfoEnum(org.h2.value.ExtTypeInfoEnum) ExtTypeInfoRow(org.h2.value.ExtTypeInfoRow) ValueBlob(org.h2.value.ValueBlob) Iterator(java.util.Iterator) BigInteger(java.math.BigInteger) ValueClob(org.h2.value.ValueClob) DataUtils.readString(org.h2.mvstore.DataUtils.readString) TypeInfo(org.h2.value.TypeInfo) ValueBigint(org.h2.value.ValueBigint) ValueTinyint(org.h2.value.ValueTinyint) ValueSmallint(org.h2.value.ValueSmallint) BigDecimal(java.math.BigDecimal)

Example 3 with ExtTypeInfoRow

use of org.h2.value.ExtTypeInfoRow in project h2database by h2database.

the class Parser method parseRowType.

private TypeInfo parseRowType() {
    read(OPEN_PAREN);
    LinkedHashMap<String, TypeInfo> fields = new LinkedHashMap<>();
    do {
        String name = readIdentifier();
        if (fields.putIfAbsent(name, parseDataType()) != null) {
            throw DbException.get(ErrorCode.DUPLICATE_COLUMN_NAME_1, name);
        }
    } while (readIfMore());
    return TypeInfo.getTypeInfo(Value.ROW, -1L, -1, new ExtTypeInfoRow(fields));
}
Also used : ExtTypeInfoRow(org.h2.value.ExtTypeInfoRow) TypeInfo(org.h2.value.TypeInfo) LinkedHashMap(java.util.LinkedHashMap)

Example 4 with ExtTypeInfoRow

use of org.h2.value.ExtTypeInfoRow in project SpringStudy by myounghaklee.

the class Parser method parseRowType.

private TypeInfo parseRowType() {
    read(OPEN_PAREN);
    LinkedHashMap<String, TypeInfo> fields = new LinkedHashMap<>();
    do {
        String name = readIdentifier();
        if (fields.putIfAbsent(name, parseDataType()) != null) {
            throw DbException.get(ErrorCode.DUPLICATE_COLUMN_NAME_1, name);
        }
    } while (readIfMore());
    return TypeInfo.getTypeInfo(Value.ROW, -1L, -1, new ExtTypeInfoRow(fields));
}
Also used : ExtTypeInfoRow(org.h2.value.ExtTypeInfoRow) TypeInfo(org.h2.value.TypeInfo) LinkedHashMap(java.util.LinkedHashMap)

Example 5 with ExtTypeInfoRow

use of org.h2.value.ExtTypeInfoRow in project 468H2Project by lukeunderwood42.

the class FieldReference method optimize.

@Override
public Expression optimize(SessionLocal session) {
    arg = arg.optimize(session);
    TypeInfo type = arg.getType();
    if (type.getValueType() != Value.ROW) {
        throw DbException.getInvalidExpressionTypeException("ROW", arg);
    }
    int ordinal = 0;
    for (Entry<String, TypeInfo> entry : ((ExtTypeInfoRow) type.getExtTypeInfo()).getFields()) {
        if (fieldName.equals(entry.getKey())) {
            type = entry.getValue();
            this.type = type;
            this.ordinal = ordinal;
            if (arg.isConstant()) {
                return TypedValueExpression.get(getValue(session), type);
            }
            return this;
        }
        ordinal++;
    }
    throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, fieldName);
}
Also used : ExtTypeInfoRow(org.h2.value.ExtTypeInfoRow) TypeInfo(org.h2.value.TypeInfo)

Aggregations

ExtTypeInfoRow (org.h2.value.ExtTypeInfoRow)12 TypeInfo (org.h2.value.TypeInfo)9 LinkedHashMap (java.util.LinkedHashMap)6 ValueBigint (org.h2.value.ValueBigint)6 BigDecimal (java.math.BigDecimal)3 BigInteger (java.math.BigInteger)3 Iterator (java.util.Iterator)3 QueryOrderBy (org.h2.command.query.QueryOrderBy)3 Expression (org.h2.expression.Expression)3 ValueExpression (org.h2.expression.ValueExpression)3 DataUtils.readString (org.h2.mvstore.DataUtils.readString)3 ExtTypeInfoEnum (org.h2.value.ExtTypeInfoEnum)3 ValueBlob (org.h2.value.ValueBlob)3 ValueClob (org.h2.value.ValueClob)3 ValueSmallint (org.h2.value.ValueSmallint)3 ValueTinyint (org.h2.value.ValueTinyint)3