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

create expression symbol after reading index meta data #2948

Merged
merged 2 commits into from
Nov 19, 2015
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
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