Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE #76]make having filter right #75

Merged
merged 2 commits into from
Jan 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<maven.compiler.target>8</maven.compiler.target>
<rocketmq-streams.version>1.1.1-SNAPSHOT</rocketmq-streams.version>
<antlr.version>4.9.2</antlr.version>
<slf4j-api.version>1.7.26</slf4j-api.version>
<logback.version>1.2.10</logback.version>
<jackson.version>2.13.4.1</jackson.version>
</properties>
Expand Down Expand Up @@ -58,6 +59,12 @@
<version>${jackson.version}</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
Expand Down Expand Up @@ -95,7 +102,21 @@
</dependencies>
</dependencyManagement>



<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<compilerVersion>${maven.compiler.source}</compilerVersion>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
</plugins>
</build>

</project>
9 changes: 9 additions & 0 deletions rsqldb-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,14 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,13 @@
package com.alibaba.rsqldb.common.function;

import com.alibaba.rsqldb.common.RSQLConstant;
import com.alibaba.rsqldb.common.exception.RSQLServerException;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.NumberDeserializers;
import com.fasterxml.jackson.databind.node.NumericNode;
import com.sun.org.slf4j.internal.Logger;
import com.sun.org.slf4j.internal.LoggerFactory;
import javafx.util.converter.BigDecimalStringConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,21 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

//一定会和groupby一起使用
// HAVING aggregate_function(column_name) operator value;
@JsonIgnoreProperties(ignoreUnknown = true)
public class SingleValueCalcuExpression extends SingleValueExpression {
private static final Logger logger = LoggerFactory.getLogger(SingleValueCalcuExpression.class);

private Calculator calculator;
private Map<String/*tableName@fieldName@asFieldName*/, String/*asName*/> field2AsName = new HashMap<>();

@JsonCreator
public SingleValueCalcuExpression(@JsonProperty("content") String content, @JsonProperty("field") Field field,
Expand All @@ -45,4 +54,20 @@ public Calculator getCalculator() {
public void setCalculator(Calculator calculator) {
this.calculator = calculator;
}

@Override
public boolean isTrue(JsonNode jsonNode) {
if (jsonNode == null) {
return false;
}

Field field = super.getField();
String asFieldName = field.getAsFieldName();
if (StringUtils.isBlank(asFieldName)) {
logger.error("the asName can not be empty, it can not judge the having sentence.");
return false;
}

return isTrue(jsonNode, asFieldName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public void setValue(Literal<?> value) {
@Override
public boolean isTrue(JsonNode jsonNode) {
String fieldName = this.getField().getFieldName();
return isTrue(jsonNode, fieldName);
}

protected boolean isTrue(JsonNode jsonNode, String fieldName) {
JsonNode node = jsonNode.get(fieldName);
if (node == null || StringUtils.isBlank(node.asText()) || stringNull.equalsIgnoreCase(node.asText())) {
return this.value == null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public GroupByQueryStatement(String content, String tableName,
}
this.groupByField = groupByField;
validate();
super.validate(havingExpression);
super.validAndPrePareHavingExpression(havingExpression);
}

@JsonCreator
Expand All @@ -84,13 +84,14 @@ public GroupByQueryStatement(@JsonProperty("content") String content, @JsonPrope
this.havingExpression = havingExpression;
this.groupByField = groupByField;
validate();
super.validate(havingExpression);
super.validAndPrePareHavingExpression(havingExpression);
}

/**
* 【否】groupBy字段包含于select字段
* groupBy字段的表名 = tableName
* 【否】select上的字段,如果没有计算符,必须在groupBy上
* having 的字段必须出现在select上
*/
private void validate() {
if (groupByField == null || groupByField.size() == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;


Expand Down Expand Up @@ -177,53 +178,49 @@ public void setSelectFieldAndCalculator(Map<Field, Calculator> selectFieldAndCal
this.selectFieldAndCalculator = selectFieldAndCalculator;
}



//having 子句中的每一个元素也必须出现在select列表中
protected List<Pair<Field, Calculator>> validate(Expression havingExpression) {
List<Pair<Field, Calculator>> havingFields = new ArrayList<>();
collect(havingExpression, havingFields);
protected void validAndPrePareHavingExpression(Expression havingExpression) {
if (havingExpression == null) {
return;
}

if (isSelectAll()) {
//select * from...
return havingFields;
throw new SyntaxErrorException("select * can not occur in having sql, sql=" + this.getContent());
}

for (Pair<Field, Calculator> pair : havingFields) {
String name = pair.getKey().getFieldName();
Calculator calculator = pair.getValue();

boolean calculatorInSelect = this.checkInSelect(name, calculator);

if (!inSelectField(name) || !calculatorInSelect) {
throw new SyntaxErrorException("field in having but not in select. sql=" + this.getContent());
}
}

return havingFields;
}

private void collect(Expression havingExpression, List<Pair<Field, Calculator>> fields) {
if (havingExpression instanceof AndExpression) {
AndExpression andExpression = (AndExpression) havingExpression;
collect(andExpression.getLeftExpression(), fields);
collect(andExpression.getRightExpression(), fields);
validAndPrePareHavingExpression(andExpression.getLeftExpression());
validAndPrePareHavingExpression(andExpression.getRightExpression());
} else if (havingExpression instanceof OrExpression) {
OrExpression orExpression = (OrExpression) havingExpression;
collect(orExpression.getLeftExpression(), fields);
collect(orExpression.getRightExpression(), fields);
} else if (havingExpression instanceof SingleExpression) {
SingleExpression expression = (SingleExpression) havingExpression;
Field fieldName = expression.getField();
Calculator calculator = null;
if (havingExpression instanceof SingleValueCalcuExpression) {
SingleValueCalcuExpression valueCalcuExpression = (SingleValueCalcuExpression) havingExpression;
calculator = valueCalcuExpression.getCalculator();
validAndPrePareHavingExpression(orExpression.getLeftExpression());
validAndPrePareHavingExpression(orExpression.getRightExpression());
} else if (havingExpression instanceof SingleValueCalcuExpression) {
SingleValueCalcuExpression calcuExpression = (SingleValueCalcuExpression) havingExpression;
Field havingField = calcuExpression.getField();
String fieldName = havingField.getFieldName();

HashMap<String, String> fieldName2AsName = this.fieldName2AsName();

String asName;
if (!checkInSelect(fieldName, calcuExpression.getCalculator())) {
throw new SyntaxErrorException("field in having but not in select. sql=" + this.getContent());
} else {
asName = fieldName2AsName.get(fieldName);
}

Pair<Field, Calculator> pair = new Pair<>(fieldName, calculator);
fields.add(pair);
/**
* use to judge the truth of having sentence {@link SingleValueCalcuExpression#isTrue(JsonNode)}
*/
havingField.setAsFieldName(asName);
}
}


@Override
public BuildContext build(BuildContext context) throws Throwable {
if (isSelectAll()) {
Expand Down Expand Up @@ -253,20 +250,6 @@ protected Accumulator<JsonNode, ObjectNode> buildAccumulator() {
return new RSQLAccumulator(sqlFunctions);
}


private boolean inSelectField(String fieldName) {
if (StringUtils.isEmpty(fieldName)) {
return false;
}

for (Field field : selectFieldAndCalculator.keySet()) {
if (fieldName.equals(field.getFieldName())) {
return true;
}
}
return false;
}

private boolean checkInSelect(String fieldName, Calculator checkCalculator) {
if (StringUtils.isEmpty(fieldName) || checkCalculator == null) {
return false;
Expand Down Expand Up @@ -327,4 +310,6 @@ private String getAsName(Field field) {

return asFieldName;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public JointGroupByHavingStatement(@JsonProperty("content") String content, @Jso
@JsonProperty("joinCondition") JoinCondition joinCondition, @JsonProperty("groupByField") List<Field> groupByField,
@JsonProperty("havingExpression") Expression havingExpression) {
super(content, tableName, selectFieldAndCalculator, joinType, asSourceTableName, joinTableName, asJoinTableName, joinCondition, groupByField);
super.validAndPrePareHavingExpression(havingExpression);
this.havingExpression = havingExpression;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public JointWhereGBHavingStatement(String content, String tableName,
List<Field> groupByField, Expression havingExpression) {
super(content, tableName, selectFieldAndCalculator, joinType, asSourceTableName, joinTableName, asJoinTableName,
joinCondition, expression, before, groupByField);
super.validAndPrePareHavingExpression(havingExpression);
this.havingExpression = havingExpression;
}

Expand Down
Loading