use of org.apache.phoenix.parse.BindParseNode in project phoenix by apache.
the class CreateSequenceCompiler method compile.
public MutationPlan compile(final CreateSequenceStatement sequence) throws SQLException {
ParseNode startsWithNode = sequence.getStartWith();
ParseNode incrementByNode = sequence.getIncrementBy();
ParseNode maxValueNode = sequence.getMaxValue();
ParseNode minValueNode = sequence.getMinValue();
ParseNode cacheNode = sequence.getCacheSize();
// validate parse nodes
if (startsWithNode != null) {
validateNodeIsStateless(sequence, startsWithNode, SQLExceptionCode.START_WITH_MUST_BE_CONSTANT);
}
validateNodeIsStateless(sequence, incrementByNode, SQLExceptionCode.INCREMENT_BY_MUST_BE_CONSTANT);
validateNodeIsStateless(sequence, maxValueNode, SQLExceptionCode.MAXVALUE_MUST_BE_CONSTANT);
validateNodeIsStateless(sequence, minValueNode, SQLExceptionCode.MINVALUE_MUST_BE_CONSTANT);
if (cacheNode != null) {
validateNodeIsStateless(sequence, cacheNode, SQLExceptionCode.CACHE_MUST_BE_NON_NEGATIVE_CONSTANT);
}
final PhoenixConnection connection = statement.getConnection();
final StatementContext context = new StatementContext(statement);
// add param meta data if required
if (startsWithNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) startsWithNode, LONG_DATUM);
}
if (incrementByNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) incrementByNode, LONG_DATUM);
}
if (maxValueNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) maxValueNode, LONG_DATUM);
}
if (minValueNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) minValueNode, LONG_DATUM);
}
if (cacheNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) cacheNode, INTEGER_DATUM);
}
ExpressionCompiler expressionCompiler = new ExpressionCompiler(context);
final long incrementBy = evalExpression(sequence, context, incrementByNode.accept(expressionCompiler), SQLExceptionCode.INCREMENT_BY_MUST_BE_CONSTANT);
if (incrementBy == 0) {
throw SequenceUtil.getException(sequence.getSequenceName().getSchemaName(), sequence.getSequenceName().getTableName(), SQLExceptionCode.INCREMENT_BY_MUST_NOT_BE_ZERO);
}
final long maxValue = evalExpression(sequence, context, maxValueNode.accept(expressionCompiler), SQLExceptionCode.MAXVALUE_MUST_BE_CONSTANT);
final long minValue = evalExpression(sequence, context, minValueNode.accept(expressionCompiler), SQLExceptionCode.MINVALUE_MUST_BE_CONSTANT);
if (minValue > maxValue) {
TableName sequenceName = sequence.getSequenceName();
throw SequenceUtil.getException(sequenceName.getSchemaName(), sequenceName.getTableName(), SQLExceptionCode.MINVALUE_MUST_BE_LESS_THAN_OR_EQUAL_TO_MAXVALUE);
}
long startsWithValue;
if (startsWithNode == null) {
startsWithValue = incrementBy > 0 ? minValue : maxValue;
} else {
startsWithValue = evalExpression(sequence, context, startsWithNode.accept(expressionCompiler), SQLExceptionCode.START_WITH_MUST_BE_CONSTANT);
if (startsWithValue < minValue || startsWithValue > maxValue) {
TableName sequenceName = sequence.getSequenceName();
throw SequenceUtil.getException(sequenceName.getSchemaName(), sequenceName.getTableName(), SQLExceptionCode.STARTS_WITH_MUST_BE_BETWEEN_MIN_MAX_VALUE);
}
}
final long startsWith = startsWithValue;
long cacheSizeValue;
if (cacheNode == null) {
cacheSizeValue = connection.getQueryServices().getProps().getLong(QueryServices.SEQUENCE_CACHE_SIZE_ATTRIB, QueryServicesOptions.DEFAULT_SEQUENCE_CACHE_SIZE);
} else {
cacheSizeValue = evalExpression(sequence, context, cacheNode.accept(expressionCompiler), SQLExceptionCode.CACHE_MUST_BE_NON_NEGATIVE_CONSTANT);
if (cacheSizeValue < 0) {
TableName sequenceName = sequence.getSequenceName();
throw SequenceUtil.getException(sequenceName.getSchemaName(), sequenceName.getTableName(), SQLExceptionCode.CACHE_MUST_BE_NON_NEGATIVE_CONSTANT);
}
}
final long cacheSize = Math.max(1L, cacheSizeValue);
final MetaDataClient client = new MetaDataClient(connection);
return new BaseMutationPlan(context, operation) {
@Override
public MutationState execute() throws SQLException {
return client.createSequence(sequence, startsWith, incrementBy, cacheSize, minValue, maxValue);
}
@Override
public ExplainPlan getExplainPlan() throws SQLException {
return new ExplainPlan(Collections.singletonList("CREATE SEQUENCE"));
}
};
}
use of org.apache.phoenix.parse.BindParseNode in project phoenix by apache.
the class ExpressionCompiler method visitLeave.
@Override
public Expression visitLeave(InListParseNode node, List<Expression> l) throws SQLException {
List<Expression> inChildren = l;
Expression firstChild = inChildren.get(0);
ImmutableBytesWritable ptr = context.getTempPtr();
PDataType firstChildType = firstChild.getDataType();
ParseNode firstChildNode = node.getChildren().get(0);
if (firstChildNode instanceof BindParseNode) {
PDatum datum = firstChild;
if (firstChildType == null) {
datum = inferBindDatum(inChildren);
}
context.getBindManager().addParamMetaData((BindParseNode) firstChildNode, datum);
}
for (int i = 1; i < l.size(); i++) {
ParseNode childNode = node.getChildren().get(i);
if (childNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) childNode, firstChild);
}
}
return wrapGroupByExpression(InListExpression.create(inChildren, node.isNegate(), ptr, context.getCurrentTable().getTable().rowKeyOrderOptimizable()));
}
use of org.apache.phoenix.parse.BindParseNode in project phoenix by apache.
the class ExpressionCompiler method visitLeave.
@Override
public Expression visitLeave(LikeParseNode node, List<Expression> children) throws SQLException {
ParseNode lhsNode = node.getChildren().get(0);
ParseNode rhsNode = node.getChildren().get(1);
Expression lhs = children.get(0);
Expression rhs = children.get(1);
if (rhs.getDataType() != null && lhs.getDataType() != null && !lhs.getDataType().isCoercibleTo(rhs.getDataType()) && !rhs.getDataType().isCoercibleTo(lhs.getDataType())) {
throw TypeMismatchException.newException(lhs.getDataType(), rhs.getDataType(), node.toString());
}
if (lhsNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) lhsNode, rhs);
}
if (rhsNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) rhsNode, lhs);
}
if (rhs instanceof LiteralExpression) {
String pattern = (String) ((LiteralExpression) rhs).getValue();
if (pattern == null || pattern.length() == 0) {
return LiteralExpression.newConstant(null, rhs.getDeterminism());
}
// TODO: for pattern of '%' optimize to strlength(lhs) > 0
// We can't use lhs IS NOT NULL b/c if lhs is NULL we need
// to return NULL.
int index = LikeExpression.indexOfWildcard(pattern);
// Can't possibly be as long as the constant, then FALSE
Integer lhsMaxLength = lhs.getMaxLength();
if (lhsMaxLength != null && lhsMaxLength < index) {
return LiteralExpression.newConstant(false, rhs.getDeterminism());
}
if (index == -1) {
String rhsLiteral = LikeExpression.unescapeLike(pattern);
if (lhsMaxLength != null && lhsMaxLength != rhsLiteral.length()) {
return LiteralExpression.newConstant(false, rhs.getDeterminism());
}
if (node.getLikeType() == LikeType.CASE_SENSITIVE) {
CompareOp op = node.isNegate() ? CompareOp.NOT_EQUAL : CompareOp.EQUAL;
if (pattern.equals(rhsLiteral)) {
return new ComparisonExpression(children, op);
} else {
rhs = LiteralExpression.newConstant(rhsLiteral, PChar.INSTANCE, rhs.getDeterminism());
return new ComparisonExpression(Arrays.asList(lhs, rhs), op);
}
}
} else {
byte[] wildcardString = new byte[pattern.length()];
byte[] wildcard = { StringUtil.MULTI_CHAR_LIKE };
StringUtil.fill(wildcardString, 0, pattern.length(), wildcard, 0, 1, false);
if (pattern.equals(new String(wildcardString))) {
List<Expression> compareChildren = Arrays.asList(lhs, NOT_NULL_STRING);
return new ComparisonExpression(compareChildren, node.isNegate() ? CompareOp.LESS : CompareOp.GREATER_OR_EQUAL);
}
}
}
QueryServices services = context.getConnection().getQueryServices();
boolean useByteBasedRegex = services.getProps().getBoolean(QueryServices.USE_BYTE_BASED_REGEX_ATTRIB, QueryServicesOptions.DEFAULT_USE_BYTE_BASED_REGEX);
Expression expression;
if (useByteBasedRegex) {
expression = ByteBasedLikeExpression.create(children, node.getLikeType());
} else {
expression = StringBasedLikeExpression.create(children, node.getLikeType());
}
if (ExpressionUtil.isConstant(expression)) {
ImmutableBytesWritable ptr = context.getTempPtr();
if (!expression.evaluate(null, ptr)) {
return LiteralExpression.newConstant(null, expression.getDeterminism());
} else {
return LiteralExpression.newConstant(Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(ptr)) ^ node.isNegate(), expression.getDeterminism());
}
}
if (node.isNegate()) {
expression = new NotExpression(expression);
}
return wrapGroupByExpression(expression);
}
use of org.apache.phoenix.parse.BindParseNode in project phoenix by apache.
the class ExpressionCompiler method visitLeave.
@Override
public Expression visitLeave(CastParseNode node, List<Expression> children) throws SQLException {
ParseNode childNode = node.getChildren().get(0);
PDataType targetDataType = node.getDataType();
Expression childExpr = children.get(0);
PDataType fromDataType = childExpr.getDataType();
if (childNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) childNode, childExpr);
}
Expression expr = childExpr;
if (fromDataType != null) {
/*
* IndexStatementRewriter creates a CAST parse node when rewriting the query to use
* indexed columns. Without this check present we wrongly and unnecessarily
* end up creating a RoundExpression.
*/
if (context.getCurrentTable().getTable().getType() != PTableType.INDEX) {
expr = convertToRoundExpressionIfNeeded(fromDataType, targetDataType, children);
}
}
boolean rowKeyOrderOptimizable = context.getCurrentTable().getTable().rowKeyOrderOptimizable();
return wrapGroupByExpression(CoerceExpression.create(expr, targetDataType, SortOrder.getDefault(), expr.getMaxLength(), rowKeyOrderOptimizable));
}
use of org.apache.phoenix.parse.BindParseNode in project phoenix by apache.
the class ExpressionCompiler method visitLeave.
@Override
public Expression visitLeave(IsNullParseNode node, List<Expression> children) throws SQLException {
ParseNode childNode = node.getChildren().get(0);
Expression child = children.get(0);
if (childNode instanceof BindParseNode) {
// TODO: valid/possibe?
context.getBindManager().addParamMetaData((BindParseNode) childNode, child);
}
return wrapGroupByExpression(IsNullExpression.create(child, node.isNegate(), context.getTempPtr()));
}
Aggregations