[ 
https://issues.apache.org/jira/browse/PHOENIX-10?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13893713#comment-13893713
 ] 

James Taylor edited comment on PHOENIX-10 at 2/6/14 7:46 PM:
-------------------------------------------------------------

Thanks, [~ram_krish]. Let me know if you have any more questions. Appreciate 
the contributions!

For the retrieval of the KV on the client side, you'll get that almost for free 
by doing the above. You just need to implement the 
wrapFuncInArrayElemRefExpression call to instantiate a new instance of a new 
ArrayIndexExpression class. Actually, it won't wrap the original 
ArrayIndexFunction expression, it'll replace it. So maybe call it 
replaceArrayIndexFunction(int position). Create this new class 
(ArrayIndexExpression) as an inner class of ProjectionCompiler, as you'll need 
state from this class and you don't have it all yet at construction time. 
You'll need the KeyValueSchema which you can only build after having visited 
all select expressions. You'll have an inner class like this:

{code}
    static class ArrayIndexExpression extends BaseTerminalExpression {
        private final int position;
        public ArrayIndexExpression(int position) {
                this.position = position;
        }
    
        @Override
        public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
            try {
                ScanProjector.decodeProjectedValue(tuple, ptr);
                int maxOffset = ptr.getOffset() + ptr.getLength();
                // arrayIndexesBitSet will be a member variable in the outer 
ProjectionCompiler class
                // It'll be created after the SelectClauseVisitor has traversed 
the expressions and
                // identified all array index refs.
                arrayIndexesBitSet.clear();
                arrayIndexesBitSet.or(ptr);
                // Same with arrayIndexesSchema. It'll be created as a 
KeyValueSchema using all the
                // ArrayIndexFunction expressions found while traversing.
                arrayIndexesSchema.iterator(ptr, position, bitSet);
                Boolean hasValue = schema.next(ptr, position, maxOffset, 
bitSet);
                if (hasValue == null || !hasValue.booleanValue())
                    return false;
            } catch (IOException e) {
                return false;
            }
            return true;
        }
{code}




was (Author: jamestaylor):
Thanks, [~ram_krish]. Let me know if you have any more questions. Appreciate 
the contributions!

For the retrieval of the KV on the client side, you'll get that almost for free 
by doing the above. You just need to implement the 
wrapFuncInArrayElemRefExpression(Expression func, int position) call to 
instantiate a new ArrayIndexExpression. Actually, it won't wrap the original 
ArrayIndexFunction expression, it'll replace it. So maybe call it 
replaceArrayIndexFunction expression. Create this new class 
(ArrayIndexExpression) as an inner class of ProjectionCompiler, as you'll need 
state from this class and you don't have it all yet at construction time. 
You'll need the KeyValueSchema which you can only build after having visited 
all select expressions. You'll have an inner class like this:

{code}
    static class ArrayIndexExpression extends BaseTerminalExpression {
        private final int position;
        public ArrayIndexExpression(int position) {
                this.position = position;
        }
    
        @Override
        public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
            try {
                ScanProjector.decodeProjectedValue(tuple, ptr);
                int maxOffset = ptr.getOffset() + ptr.getLength();
                // arrayIndexesBitSet will be a member variable in the outer 
ProjectionCompiler class
                // It'll be created after the SelectClauseVisitor has traversed 
the expressions and
                // identified all array index refs.
                arrayIndexesBitSet.clear();
                arrayIndexesBitSet.or(ptr);
                // Same with arrayIndexesSchema. It'll be created as a 
KeyValueSchema using all the
                // ArrayIndexFunction expressions found while traversing.
                arrayIndexesSchema.iterator(ptr, position, bitSet);
                Boolean hasValue = schema.next(ptr, position, maxOffset, 
bitSet);
                if (hasValue == null || !hasValue.booleanValue())
                    return false;
            } catch (IOException e) {
                return false;
            }
            return true;
        }
{code}



> Push projection of a single ARRAY element to the server
> -------------------------------------------------------
>
>                 Key: PHOENIX-10
>                 URL: https://issues.apache.org/jira/browse/PHOENIX-10
>             Project: Phoenix
>          Issue Type: Improvement
>            Reporter: James Taylor
>            Assignee: ramkrishna.s.vasudevan
>         Attachments: Phoenix-10_1.patch
>
>
> If only a single array element is selected, we'll still return the entire 
> array back to the client. Instead, we should push this to the server and only 
> return the single array element. The same goes for the reference to an ARRAY 
> in the WHERE clause. There's a general HBase fix for this (i.e. the ability 
> to define a separate set of key values that will be returned versus key 
> values available to filters) that has a patch here, but is deemed not 
> possible to pull into the 0.94 branch by @lhofhansl.
> My thought is that we can add a Filter at the end our our filter chain that 
> filters out any KeyValues that aren't in the SELECT expressions (i.e. filter 
> out if a column is referenced in the WHERE clause, but not in the SELECT 
> expressions). This same Filter could handle returning only the elements of 
> the array that are referenced in the SELECT expression rather than the entire 
> array.



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

Reply via email to