[ 
https://issues.apache.org/jira/browse/ARROW-17430?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Igor Suhorukov updated ARROW-17430:
-----------------------------------
    Description: 
Typical real life Arrow datasets contain List type vectors of primitive type. 
Looks logically implement default JDBC parameter binders for such vector type 
or implement some kind on binder code extensibility of core framework via 
MetaINF/ServiceLocator

Current implementation just [throws UnsupportedOperationException|#L80]]

 
{code:java}
  @Override
        
        
            public ColumnBinder visit(ArrowType.List type) {
        
        
              throw new UnsupportedOperationException("No column binder 
implemented for type " + type);
        
        
            } {code}
 

My current implementation patch {color:#000000}ColumnBinderArrowTypeVisitor in 
classpath to return ListBinder{color}
{code:java}
@Override
public ColumnBinder visit(ArrowType.List type) {
    return new ListBinder((ListVector) vector);
} {code}
{color:#000000}and following code works for me with H2 database and in java 
stored PostgreSQL {color}{color:#000000}function in PL/Java to bind List 
parameter to JDBC:{color}
{code:java}
package org.apache.arrow.adapter.jdbc.binder;

import org.apache.arrow.vector.complex.ListVector;
import org.apache.arrow.vector.complex.impl.UnionListReader;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;

public class ListBinder extends BaseColumnBinder<ListVector>{

    private UnionListReader reader;

    public ListBinder(ListVector vector) {
        this(vector, Types.ARRAY);
    }

    public ListBinder(ListVector vector, int jdbcType) {
        super(vector, jdbcType);
        reader = vector.getReader();
    }

    @Override
    public void bind(PreparedStatement statement, int parameterIndex, int 
rowIndex) throws SQLException {
        reader.setPosition(rowIndex);
        ArrayList sourceArray = (ArrayList) reader.readObject();
        Class aClass = sourceArray.get(0).getClass();
        if(aClass.isAssignableFrom(Long.class)){
            Long[] res = new Long[sourceArray.size()];
            Arrays.setAll(res, sourceArray::get);
            statement.setObject(parameterIndex, res);
        } else
        if(aClass.isAssignableFrom(Integer.class)){
            Integer[] res = new Integer[sourceArray.size()];
            Arrays.setAll(res, sourceArray::get);
            statement.setObject(parameterIndex, res);
        } else
        if(aClass.isAssignableFrom(Short.class)){
            Short[] res = new Short[sourceArray.size()];
            Arrays.setAll(res, sourceArray::get);
            statement.setObject(parameterIndex, res);
        } else
        if(aClass.isAssignableFrom(String.class)){
            String[] res = new String[sourceArray.size()];
            Arrays.setAll(res, sourceArray::get);
            statement.setObject(parameterIndex, res);
        }
    }
}
 {code}

  was:
Typical real life Arrow datasets contain List type vectors of primitive type. 
Looks logically implement default JDBC parameter binders for such vector type 
or implement some kind on binder code extensibility of core framework via 
MetaINF/ServiceLocator

Current implementation just [throws UnsupportedOperationException|#L80]]

 
{code:java}
  @Override
        
        
            public ColumnBinder visit(ArrowType.List type) {
        
        
              throw new UnsupportedOperationException("No column binder 
implemented for type " + type);
        
        
            } {code}
 

My current implementation patch {color:#000000}ColumnBinderArrowTypeVisitor in 
classpath to return ListBinder{color}
{code:java}
@Override
public ColumnBinder visit(ArrowType.List type) {
    //throw new UnsupportedOperationException("No column binder implemented for 
type " + type);
    return new ListBinder((ListVector) vector);
} {code}
{color:#000000}and following code works for me with H2 database and in java 
stored PostgreSQL {color}{color:#000000}function in PL/Java to bind List 
parameter to JDBC:{color}
{code:java}
package org.apache.arrow.adapter.jdbc.binder;

import org.apache.arrow.vector.complex.ListVector;
import org.apache.arrow.vector.complex.impl.UnionListReader;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;

public class ListBinder extends BaseColumnBinder<ListVector>{

    private UnionListReader reader;

    public ListBinder(ListVector vector) {
        this(vector, Types.ARRAY);
    }

    public ListBinder(ListVector vector, int jdbcType) {
        super(vector, jdbcType);
        reader = vector.getReader();
    }

    @Override
    public void bind(PreparedStatement statement, int parameterIndex, int 
rowIndex) throws SQLException {
        reader.setPosition(rowIndex);
        ArrayList sourceArray = (ArrayList) reader.readObject();
        Class aClass = sourceArray.get(0).getClass();
        if(aClass.isAssignableFrom(Long.class)){
            Long[] res = new Long[sourceArray.size()];
            Arrays.setAll(res, sourceArray::get);
            statement.setObject(parameterIndex, res);
        } else
        if(aClass.isAssignableFrom(Integer.class)){
            Integer[] res = new Integer[sourceArray.size()];
            Arrays.setAll(res, sourceArray::get);
            statement.setObject(parameterIndex, res);
        } else
        if(aClass.isAssignableFrom(Short.class)){
            Short[] res = new Short[sourceArray.size()];
            Arrays.setAll(res, sourceArray::get);
            statement.setObject(parameterIndex, res);
        } else
        if(aClass.isAssignableFrom(String.class)){
            String[] res = new String[sourceArray.size()];
            Arrays.setAll(res, sourceArray::get);
            statement.setObject(parameterIndex, res);
        }
    }
}
 {code}


> [Java] ListBinder to bind Arrow List type to DB column 
> -------------------------------------------------------
>
>                 Key: ARROW-17430
>                 URL: https://issues.apache.org/jira/browse/ARROW-17430
>             Project: Apache Arrow
>          Issue Type: Improvement
>          Components: Java
>    Affects Versions: 10.0.0
>            Reporter: Igor Suhorukov
>            Priority: Major
>
> Typical real life Arrow datasets contain List type vectors of primitive type. 
> Looks logically implement default JDBC parameter binders for such vector type 
> or implement some kind on binder code extensibility of core framework via 
> MetaINF/ServiceLocator
> Current implementation just [throws UnsupportedOperationException|#L80]]
>  
> {code:java}
>   @Override
>         
>         
>             public ColumnBinder visit(ArrowType.List type) {
>         
>         
>               throw new UnsupportedOperationException("No column binder 
> implemented for type " + type);
>         
>         
>             } {code}
>  
> My current implementation patch {color:#000000}ColumnBinderArrowTypeVisitor 
> in classpath to return ListBinder{color}
> {code:java}
> @Override
> public ColumnBinder visit(ArrowType.List type) {
>     return new ListBinder((ListVector) vector);
> } {code}
> {color:#000000}and following code works for me with H2 database and in java 
> stored PostgreSQL {color}{color:#000000}function in PL/Java to bind List 
> parameter to JDBC:{color}
> {code:java}
> package org.apache.arrow.adapter.jdbc.binder;
> import org.apache.arrow.vector.complex.ListVector;
> import org.apache.arrow.vector.complex.impl.UnionListReader;
> import java.sql.PreparedStatement;
> import java.sql.SQLException;
> import java.sql.Types;
> import java.util.ArrayList;
> import java.util.Arrays;
> public class ListBinder extends BaseColumnBinder<ListVector>{
>     private UnionListReader reader;
>     public ListBinder(ListVector vector) {
>         this(vector, Types.ARRAY);
>     }
>     public ListBinder(ListVector vector, int jdbcType) {
>         super(vector, jdbcType);
>         reader = vector.getReader();
>     }
>     @Override
>     public void bind(PreparedStatement statement, int parameterIndex, int 
> rowIndex) throws SQLException {
>         reader.setPosition(rowIndex);
>         ArrayList sourceArray = (ArrayList) reader.readObject();
>         Class aClass = sourceArray.get(0).getClass();
>         if(aClass.isAssignableFrom(Long.class)){
>             Long[] res = new Long[sourceArray.size()];
>             Arrays.setAll(res, sourceArray::get);
>             statement.setObject(parameterIndex, res);
>         } else
>         if(aClass.isAssignableFrom(Integer.class)){
>             Integer[] res = new Integer[sourceArray.size()];
>             Arrays.setAll(res, sourceArray::get);
>             statement.setObject(parameterIndex, res);
>         } else
>         if(aClass.isAssignableFrom(Short.class)){
>             Short[] res = new Short[sourceArray.size()];
>             Arrays.setAll(res, sourceArray::get);
>             statement.setObject(parameterIndex, res);
>         } else
>         if(aClass.isAssignableFrom(String.class)){
>             String[] res = new String[sourceArray.size()];
>             Arrays.setAll(res, sourceArray::get);
>             statement.setObject(parameterIndex, res);
>         }
>     }
> }
>  {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to