Skip to content

Commit

Permalink
Merge 6089b18 into 3f1ddd7
Browse files Browse the repository at this point in the history
  • Loading branch information
seut committed Nov 19, 2015
2 parents 3f1ddd7 + 6089b18 commit 2800128
Show file tree
Hide file tree
Showing 24 changed files with 485 additions and 290 deletions.
30 changes: 16 additions & 14 deletions sql/src/main/java/io/crate/analyze/AnalyzedTableElements.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,13 @@ public void finalizeAndValidate(TableIdent tableIdent,
private void validateGeneratedColumns(TableIdent tableIdent,
AnalysisMetaData analysisMetaData,
ParameterContext parameterContext) {
List<Reference> tableReferences = new ArrayList<>();
List<ReferenceInfo> tableReferenceInfos = new ArrayList<>();
for (AnalyzedColumnDefinition columnDefinition : columns) {
buildReference(tableIdent, columnDefinition, tableReferences);
buildReferenceInfo(tableIdent, columnDefinition, tableReferenceInfos);
}

ExpressionAnalyzer expressionAnalyzer = new ExpressionReferenceAnalyzer(
analysisMetaData, parameterContext, tableReferences);
analysisMetaData, parameterContext, tableReferenceInfos);

for (AnalyzedColumnDefinition columnDefinition : columns) {
if (columnDefinition.generatedExpression() != null) {
Expand Down Expand Up @@ -214,7 +214,7 @@ private void processGeneratedExpression(ExpressionAnalyzer expressionAnalyzer, A
columnDefinition.formattedGeneratedExpression(formattedExpression);
}

private void buildReference(TableIdent tableIdent, AnalyzedColumnDefinition columnDefinition, List<Reference> referenceList) {
private void buildReferenceInfo(TableIdent tableIdent, AnalyzedColumnDefinition columnDefinition, List<ReferenceInfo> referenceInfos) {
ReferenceInfo referenceInfo;
if (columnDefinition.generatedExpression() == null) {
referenceInfo = new ReferenceInfo(
Expand All @@ -225,12 +225,13 @@ private void buildReference(TableIdent tableIdent, AnalyzedColumnDefinition colu
referenceInfo = new GeneratedReferenceInfo(
new ReferenceIdent(tableIdent, columnDefinition.ident()),
RowGranularity.DOC,
columnDefinition.dataType() == null ? DataTypes.UNDEFINED : DataTypes.ofMappingNameSafe(columnDefinition.dataType()),
columnDefinition.dataType() ==
null ? DataTypes.UNDEFINED : DataTypes.ofMappingNameSafe(columnDefinition.dataType()),
"dummy expression, real one not needed here");
}
referenceList.add(new Reference(referenceInfo));
referenceInfos.add(referenceInfo);
for (AnalyzedColumnDefinition childDefinition : columnDefinition.children()) {
buildReference(tableIdent, childDefinition, referenceList);
buildReferenceInfo(tableIdent, childDefinition, referenceInfos);
}
}

Expand Down Expand Up @@ -268,12 +269,12 @@ private void validateIndexDefinitions() {
}

public void addCopyTo(String sourceColumn, String targetIndex) {
Set<String> targetColumns = copyToMap.get(sourceColumn);
if (targetColumns == null) {
targetColumns = new HashSet<>();
copyToMap.put(sourceColumn, targetColumns);
}
targetColumns.add(targetIndex);
Set<String> targetColumns = copyToMap.get(sourceColumn);
if (targetColumns == null) {
targetColumns = new HashSet<>();
copyToMap.put(sourceColumn, targetColumns);
}
targetColumns.add(targetIndex);
}

public Set<ColumnIdent> columnIdents() {
Expand Down Expand Up @@ -346,7 +347,8 @@ public void changeToPartitionedByColumn(ColumnIdent partitionedByIdent, boolean
"Cannot use array column '%s' in PARTITIONED BY clause", columnDefinition.ident().sqlFqn()));


}if (columnDefinition.index().equals("analyzed")) {
}
if (columnDefinition.index().equals("analyzed")) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH,
"Cannot use column '%s' with fulltext index in PARTITIONED BY clause",
columnDefinition.ident().sqlFqn()));
Expand Down
81 changes: 31 additions & 50 deletions sql/src/main/java/io/crate/analyze/InsertFromValuesAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,16 @@
import com.google.common.base.Function;
import io.crate.analyze.expressions.ExpressionAnalysisContext;
import io.crate.analyze.expressions.ExpressionAnalyzer;
import io.crate.analyze.expressions.ExpressionReferenceValueAnalyzer;
import io.crate.analyze.relations.DocTableRelation;
import io.crate.analyze.relations.FieldProvider;
import io.crate.analyze.relations.NameFieldProvider;
import io.crate.analyze.symbol.*;
import io.crate.core.StringUtils;
import io.crate.core.collections.StringObjectMaps;
import io.crate.exceptions.ColumnUnknownException;
import io.crate.exceptions.ColumnValidationException;
import io.crate.metadata.ColumnIdent;
import io.crate.metadata.GeneratedReferenceInfo;
import io.crate.metadata.ReferenceInfo;
import io.crate.metadata.TableIdent;
import io.crate.metadata.*;
import io.crate.metadata.doc.DocTableInfo;
import io.crate.operation.Input;
import io.crate.sql.parser.SqlParser;
import io.crate.sql.tree.Assignment;
import io.crate.sql.tree.Expression;
import io.crate.sql.tree.InsertFromValues;
Expand All @@ -56,6 +50,8 @@
@Singleton
public class InsertFromValuesAnalyzer extends AbstractInsertAnalyzer {

private static final ReferenceToLiteralConverter TO_LITERAL_CONVERTER = new ReferenceToLiteralConverter();

private static class ValuesResolver implements io.crate.analyze.ValuesAwareExpressionAnalyzer.ValuesResolver {

private final DocTableRelation tableRelation;
Expand Down Expand Up @@ -108,9 +104,6 @@ public AbstractInsertAnalyzedStatement visitInsertFromValues(InsertFromValues no
tableInfo, analysis.parameterContext().hasBulkParams());
handleInsertColumns(node, node.maxValuesLength(), statement);

ExpressionReferenceValueAnalyzer referenceValueAnalyzer = new ExpressionReferenceValueAnalyzer(
tableInfo, statement.columns(), analysisMetaData, analysis.parameterContext());

for (ValuesList valuesList : node.valuesLists()) {
analyzeValues(
tableRelation,
Expand All @@ -121,8 +114,7 @@ public AbstractInsertAnalyzedStatement visitInsertFromValues(InsertFromValues no
valuesList,
node.onDuplicateKeyAssignments(),
statement,
analysis.parameterContext(),
referenceValueAnalyzer);
analysis.parameterContext());
}
return statement;
}
Expand All @@ -135,8 +127,7 @@ private void analyzeValues(DocTableRelation tableRelation,
ValuesList node,
List<Assignment> assignments,
InsertFromValuesAnalyzedStatement statement,
ParameterContext parameterContext,
ExpressionReferenceValueAnalyzer referenceValueAnalyzer) {
ParameterContext parameterContext) {
if (node.values().size() != statement.columns().size()) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH,
"Invalid number of values: Got %d columns specified but %d values",
Expand All @@ -155,7 +146,6 @@ private void analyzeValues(DocTableRelation tableRelation,
expressionAnalysisContext,
valuesResolver,
valuesAwareExpressionAnalyzer,
referenceValueAnalyzer,
node,
assignments,
statement,
Expand All @@ -170,7 +160,6 @@ private void analyzeValues(DocTableRelation tableRelation,
expressionAnalysisContext,
valuesResolver,
valuesAwareExpressionAnalyzer,
referenceValueAnalyzer,
node,
assignments,
statement,
Expand All @@ -188,7 +177,6 @@ private void addValues(DocTableRelation tableRelation,
ExpressionAnalysisContext expressionAnalysisContext,
ValuesResolver valuesResolver,
ExpressionAnalyzer valuesAwareExpressionAnalyzer,
ExpressionReferenceValueAnalyzer referenceValueAnalyzer,
ValuesList node,
List<Assignment> assignments,
InsertFromValuesAnalyzedStatement context,
Expand Down Expand Up @@ -283,7 +271,7 @@ private void addValues(DocTableRelation tableRelation,
}

// process generated column expressions and add columns + values
insertValues = processGeneratedExpressions(tableRelation, expressionAnalysisContext, referenceValueAnalyzer, context, insertValues);
insertValues = processGeneratedExpressions(tableRelation, context, expressionAnalyzer, insertValues);

context.sourceMaps().add(insertValues);
context.addIdAndRouting(idFunction.apply(primaryKeyValues), routingValue);
Expand Down Expand Up @@ -346,42 +334,35 @@ private Object processPartitionedByValues(final ColumnIdent columnIdent, Object
}

private Object[] processGeneratedExpressions(DocTableRelation tableRelation,
ExpressionAnalysisContext expressionAnalysisContext,
ExpressionReferenceValueAnalyzer referenceValueAnalyzer,
InsertFromValuesAnalyzedStatement context,
Object[] insertValues) {
referenceValueAnalyzer.values(insertValues);
InsertFromValuesAnalyzedStatement context,
ExpressionAnalyzer expressionAnalyzer,
Object[] insertValues) {
ReferenceToLiteralConverter.Context toLiteralContext = new ReferenceToLiteralConverter.Context(context.columns(), insertValues);
for (ReferenceInfo referenceInfo : tableRelation.tableInfo().columns()) {
if (referenceInfo instanceof GeneratedReferenceInfo) {
Reference reference = new Reference(referenceInfo);
String formattedExpression = ((GeneratedReferenceInfo) referenceInfo).generatedExpression();
Expression expression = SqlParser.createExpression(formattedExpression);
Symbol valueSymbol;
try {
valueSymbol = referenceValueAnalyzer.normalize(referenceValueAnalyzer.convert(expression, expressionAnalysisContext));
} catch (ColumnUnknownException e) {
// this should never happen because expression was already validated on table creation
throw new IllegalStateException("Expression is invalid, referenced column not found", e);
}
Object value = null;
Symbol valueSymbol = TO_LITERAL_CONVERTER.process(
((GeneratedReferenceInfo) referenceInfo).generatedExpression(),
toLiteralContext);
valueSymbol = expressionAnalyzer.normalize(valueSymbol);
if (valueSymbol.isLiteral()) {
value = ((Input) valueSymbol).value();
}
int idx = context.columns().indexOf(reference);
if (idx == -1) {
// add column & value
context.columns().add(reference);
int valuesIdx = insertValues.length;
insertValues = Arrays.copyOf(insertValues, insertValues.length + 1);
insertValues[valuesIdx] = value;
} else if (insertValues.length <= idx) {
// only add value
insertValues = Arrays.copyOf(insertValues, idx + 1);
insertValues[idx] = value;
} else if (!insertValues[idx].equals(value)) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH,
"Given value %s for generated column does not match defined generated expression value %s",
insertValues[idx], value));
Object value = ((Input) valueSymbol).value();
int idx = context.columns().indexOf(reference);
if (idx == -1) {
// add column & value
context.columns().add(reference);
int valuesIdx = insertValues.length;
insertValues = Arrays.copyOf(insertValues, insertValues.length + 1);
insertValues[valuesIdx] = value;
} else if (insertValues.length <= idx) {
// only add value
insertValues = Arrays.copyOf(insertValues, idx + 1);
insertValues[idx] = value;
} else if (!insertValues[idx].equals(value)) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH,
"Given value %s for generated column does not match defined generated expression value %s",
insertValues[idx], value));
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private List<ColumnDefinition> extractColumnDefinitions(@Nullable ColumnIdent pa
}
Expression expression = null;
if (info instanceof GeneratedReferenceInfo) {
String formattedExpression = ((GeneratedReferenceInfo) info).generatedExpression();
String formattedExpression = ((GeneratedReferenceInfo) info).formattedGeneratedExpression();
expression = SqlParser.createExpression(formattedExpression);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
import io.crate.analyze.EvaluatingNormalizer;
import io.crate.analyze.symbol.Function;
import io.crate.analyze.symbol.Literal;
import io.crate.analyze.symbol.Reference;
import io.crate.analyze.symbol.Symbol;
import io.crate.metadata.FunctionInfo;
import io.crate.operation.scalar.timestamp.CurrentTimestampFunction;
import io.crate.sql.tree.CurrentTime;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -42,6 +44,8 @@ public class ExpressionAnalysisContext {
private final Map<CurrentTime, Literal> allocatedCurrentTimestamps = new HashMap<>();

private final Map<Function, Function> deterministicFunctionSymbols = new HashMap<>();
private final List<Reference> references = new ArrayList<>();

public boolean hasAggregates = false;

public ExpressionAnalysisContext() {
Expand Down Expand Up @@ -77,4 +81,18 @@ public Symbol allocateCurrentTime(CurrentTime node, List<Symbol> args, Evaluatin
}
return literal;
}

/**
* Add a reference the expression is based on
*/
public void addReference(Reference reference) {
references.add(reference);
}

/**
* Returns a list of references which the expression is based on
*/
public List<Reference> references() {
return references;
}
}
Loading

0 comments on commit 2800128

Please sign in to comment.