Skip to content

Commit

Permalink
MODE-1496 JCR-3313 Added fixed JCR TCK test and corrected result set …
Browse files Browse the repository at this point in the history
…column behavior

Corrected the behavior of query result column names when the query contains a wildcard in the SELECT statement.
  • Loading branch information
rhauch committed May 31, 2012
1 parent dc9c905 commit b518687
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,14 @@ public org.modeshape.jcr.api.query.Query createQuery( String expression,
// The query is not well-formed and cannot be parsed ...
throw new InvalidQueryException(JcrI18n.queryCannotBeParsedUsingLanguage.text(language, expression));
}
// Set up the hints ...
PlanHints hints = new PlanHints();
hints.showPlan = true;
hints.hasFullTextSearch = true; // always include the score
hints.validateColumnExistance = false; // see MODE-1055
if (parser.getLanguage().equals(QueryLanguage.JCR_SQL2)) {
hints.qualifyExpandedColumnNames = true;
}
return resultWith(expression, parser.getLanguage(), command, hints, storedAtPath);
} catch (ParsingException e) {
// The query is not well-formed and cannot be parsed ...
Expand Down Expand Up @@ -173,6 +177,7 @@ public Query createQuery( QueryCommand command ) throws InvalidQueryException, R
PlanHints hints = new PlanHints();
hints.showPlan = true;
hints.hasFullTextSearch = true; // always include the score
hints.qualifyExpandedColumnNames = true; // always qualify expanded names with the selector name in JCR-SQL2
return resultWith(expression, QueryLanguage.JCR_SQL2, command, hints, null);
} catch (org.modeshape.jcr.query.parse.InvalidQueryException e) {
// The query was parsed, but there is an error in the query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
import org.modeshape.jcr.query.QueryResults.Columns;
import org.modeshape.jcr.query.QueryResults.Location;
import org.modeshape.jcr.query.validate.Schemata;

Expand All @@ -57,14 +58,17 @@ public XPathQueryResult( JcrQueryContext context,
QueryResults graphResults,
Schemata schemata ) {
super(context, query, graphResults, schemata);
List<String> columnNames = new LinkedList<String>(graphResults.getColumns().getColumnNames());
List<String> columnTypes = new LinkedList<String>(graphResults.getColumns().getColumnTypes());
if (graphResults.getColumns().hasFullTextSearchScores() && !columnNames.contains(JCR_SCORE_COLUMN_NAME)) {
Columns resultColumns = graphResults.getColumns();
List<String> columnNames = new LinkedList<String>(resultColumns.getColumnNames());
List<String> columnTypes = new LinkedList<String>(resultColumns.getColumnTypes());
if (resultColumns.hasFullTextSearchScores() && !columnNames.contains(JCR_SCORE_COLUMN_NAME)) {
columnNames.add(0, JCR_SCORE_COLUMN_NAME);
columnTypes.add(0, JCR_SCORE_COLUMN_TYPE);
}
columnNames.add(0, JCR_PATH_COLUMN_NAME);
columnTypes.add(0, JCR_PATH_COLUMN_TYPE);
if (!resultColumns.getColumnNames().contains(JCR_PATH_COLUMN_NAME)) {
columnNames.add(0, JCR_PATH_COLUMN_NAME);
columnTypes.add(0, JCR_PATH_COLUMN_TYPE);
}
this.columnNames = Collections.unmodifiableList(columnNames);
this.columnTypes = Collections.unmodifiableList(columnTypes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ public Column with( SelectorName newSelectorName ) {
return new Column(newSelectorName, propertyName, columnName);
}

public Column withColumnName( String columnName ) {
return new Column(selectorName, propertyName, columnName);
}

@Override
public void accept( Visitor visitor ) {
visitor.visit(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,7 @@ public void visit( Literal literal ) {
Object value = literal.value();
String typeName = null;
ValueFactories factories = context.getValueFactories();
if (value instanceof String) {
if (value instanceof String || value instanceof Character) {
append(SINGLE_QUOTE);
String str = factories.getStringFactory().create(value);
append(str);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,8 @@ protected PlanNode attachProject( QueryContext context,

List<Column> newColumns = new LinkedList<Column>();
List<String> newTypes = new ArrayList<String>();
final boolean multipleSelectors = selectors.size() > 1;
final boolean qualifyExpandedColumns = context.getHints().qualifyExpandedColumnNames;
if (columns == null || columns.isEmpty()) {
// SELECT *, so find all of the columns that are available from all the sources ...
for (Map.Entry<SelectorName, Table> entry : selectors.entrySet()) {
Expand All @@ -455,7 +457,7 @@ protected PlanNode attachProject( QueryContext context,
// Add the selector that is being used ...
projectNode.addSelector(tableName);
// Compute the columns from this selector ...
allColumnsFor(table, tableName, newColumns, newTypes, false);
allColumnsFor(table, tableName, newColumns, newTypes, qualifyExpandedColumns);
}
} else {
// Add the selector used by each column ...
Expand All @@ -474,10 +476,13 @@ protected PlanNode attachProject( QueryContext context,
if ("*".equals(columnName) || columnName == null) {
// This is a 'SELECT *' on this source, but this source is one of multiple sources ...
// See https://issues.apache.org/jira/browse/JCR-3313; TCK test expects 'true' for last param
allColumnsFor(table, tableName, newColumns, newTypes, false);
allColumnsFor(table, tableName, newColumns, newTypes, qualifyExpandedColumns);
} else {
// This is a particular column, so add it ...
if (!newColumns.contains(column)) {
if (multipleSelectors && column.getPropertyName().equals(column.getColumnName())) {
column = column.withColumnName(column.getSelectorName() + "." + column.getColumnName());
}
newColumns.add(column);
org.modeshape.jcr.query.validate.Schemata.Column schemaColumn = table.getColumn(columnName);
if (schemaColumn != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ public final class PlanHints implements Serializable, Cloneable {
*/
public boolean useSessionContent = true;

/**
* Flag indicates whether to fully-qualify (with the selector name) the names of columns that are expanded from wildcard
* projections.
*/
public boolean qualifyExpandedColumnNames = false;

public PlanHints() {
}

Expand All @@ -103,6 +109,8 @@ public String toString() {
sb.append(", showPlan=").append(showPlan);
sb.append(", validateColumnExistance=").append(validateColumnExistance);
sb.append(", includeSystemContent=").append(includeSystemContent);
sb.append(", useSessionContent=").append(useSessionContent);
sb.append(", qualifyExpandedColumnNames=").append(qualifyExpandedColumnNames);
sb.append('}');
return sb.toString();
}
Expand All @@ -121,6 +129,8 @@ public PlanHints clone() {
clone.showPlan = this.showPlan;
clone.validateColumnExistance = this.validateColumnExistance;
clone.includeSystemContent = this.includeSystemContent;
clone.useSessionContent = this.useSessionContent;
clone.qualifyExpandedColumnNames = this.qualifyExpandedColumnNames;
return clone;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ private QueryResultColumns( List<Column> columns,
Integer columnIndex = wrappedAround.columnIndexForName(columnName);
if (columnIndex == null) {
String columnNameWithoutSelector = column.getColumnName() != null ? column.getColumnName() : column.getPropertyName();
if (columnNameWithoutSelector.startsWith(selectorName + ".")
&& columnNameWithoutSelector.length() > (selectorName.length() + 1)) {
columnNameWithoutSelector = columnNameWithoutSelector.substring(selectorName.length() + 1);
}
columnIndex = wrappedAround.columnIndexForName(columnNameWithoutSelector);
if (columnIndex == null) {
String columnNameWithSelector = column.selectorName() + "." + columnNameWithoutSelector;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,13 +494,19 @@ public Schemata build() {
}
}
String viewColumnName = column.getColumnName();
if (viewColumnName.equals(column.getSelectorName() + "." + column.getPropertyName())) {
viewColumnName = column.getPropertyName();
}
if (columnNames.contains(viewColumnName)) continue;
String sourceColumnName = column.getPropertyName(); // getColumnName() returns alias
Column sourceColumn = source.getColumn(sourceColumnName);
if (sourceColumn == null) {
throw new InvalidQueryException(Visitors.readable(command),
"The view references a non-existant column '"
+ column.getColumnName() + "' in '" + source.getName() + "'");
sourceColumn = source.getColumn(column.getColumnName());
if (sourceColumn == null) {
throw new InvalidQueryException(Visitors.readable(command),
"The view references a non-existant column '"
+ column.getColumnName() + "' in '" + source.getName() + "'");
}
}
Set<Operator> operators = operators(name, viewColumnName, sourceColumn.getOperators());
boolean orderable = orderable(name, viewColumnName, sourceColumn.isOrderable());
Expand Down
Loading

0 comments on commit b518687

Please sign in to comment.