1 /*
2 * Copyright (c) 2011. The Apache Software Foundation
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 package org.apache.hadoop.hbase.hbql.impl;
22
23 import org.apache.expreval.client.NullColumnValueException;
24 import org.apache.expreval.client.ResultMissingColumnException;
25 import org.apache.hadoop.hbase.client.Result;
26 import org.apache.hadoop.hbase.client.ResultScanner;
27 import org.apache.hadoop.hbase.hbql.client.HBqlException;
28 import org.apache.hadoop.hbase.hbql.mapping.ResultAccessor;
29 import org.apache.hadoop.hbase.hbql.statement.select.RowRequest;
30 import org.apache.hadoop.hbase.hbql.util.CompletionQueue;
31 import org.apache.hadoop.hbase.hbql.util.NullIterator;
32
33 import java.util.Iterator;
34 import java.util.List;
35
36
37 public class ResultExecutorResultSet<T> extends HResultSetImpl<T, Result> {
38
39 ResultExecutorResultSet(final Query<T> query, final ResultExecutor executor) throws HBqlException {
40 super(query, executor);
41 }
42
43 protected void submitWork(final List<RowRequest> rowRequestList) {
44
45 // This will submit jobs until a job is rejected, at which point, execution will take place in
46 // the context of this thread
47 for (final RowRequest rowRequest : rowRequestList) {
48 this.getCompletionQueueExecutor().submitWorkToThreadPool(
49 new Runnable() {
50 public void run() {
51 HBqlException outerException = null;
52 try {
53 final ResultScanner scanner = rowRequest.getResultScanner(getMappingContext().getMapping(),
54 getWithArgs(),
55 getTableWrapper().getHTable());
56 for (final Result result : scanner) {
57
58 try {
59 if (getClientExpressionTree() != null
60 && !getClientExpressionTree().evaluate(getHConnectionImpl(), result))
61 continue;
62 }
63 catch (ResultMissingColumnException e) {
64 continue;
65 }
66 catch (NullColumnValueException e) {
67 continue;
68 }
69
70 getCompletionQueueExecutor().putElement(result);
71 }
72
73 scanner.close();
74 }
75 catch (HBqlException e) {
76 outerException = e;
77 }
78 finally {
79 if (outerException != null)
80 getCompletionQueueExecutor().addException(outerException);
81
82 getCompletionQueueExecutor().putCompletion();
83 }
84 }
85 });
86 }
87 }
88
89 public Iterator<T> iterator() {
90
91 try {
92 return new ResultSetIterator<T, Result>(this) {
93
94 protected boolean moreResultsPending() {
95 return getCompletionQueueExecutor().moreResultsPending();
96 }
97
98 protected Iterator<Result> getNextResultIterator() throws HBqlException {
99 return null;
100 }
101
102 @SuppressWarnings("unchecked")
103 protected T fetchNextObject() throws HBqlException {
104
105 final ResultAccessor resultAccessor = getMappingContext().getResultAccessor();
106
107 // Read data until all jobs have sent DONE tokens
108 while (true) {
109 final Result result;
110 final CompletionQueue.Element<Result> element = getCompletionQueueExecutor().takeElement();
111 if (element.isCompletionToken()) {
112 if (!moreResultsPending())
113 break;
114 else
115 continue;
116 }
117 else {
118 result = element.getValue();
119 }
120
121 this.incrementReturnedRecordCount();
122
123 if (getSelectStmt().isAnAggregateQuery()) {
124 getAggregateRecord().applyValues(result);
125 }
126 else {
127 final T val = (T)resultAccessor.newObject(getHConnectionImpl(),
128 getMappingContext(),
129 getSelectStmt().getSelectElementList(),
130 getMaxVersions(),
131 result);
132 return getQuery().callOnEachRow(val);
133 }
134 }
135
136 if (getSelectStmt().isAnAggregateQuery() && getAggregateRecord() != null) {
137
138 // Stash the value and then null it out for next time through
139 final AggregateRecord retval = getAggregateRecord();
140 setAggregateRecord(null);
141
142 return getQuery().callOnEachRow((T)retval);
143 }
144
145 this.markIteratorComplete();
146 return null;
147 }
148 };
149 }
150 catch (HBqlException e) {
151 e.printStackTrace();
152 getQuery().callOnException(e);
153 return new NullIterator<T>();
154 }
155 }
156 }