/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.calcite.avatica;

import org.apache.calcite.avatica.ColumnMetaData.AvaticaType;
import org.apache.calcite.avatica.remote.TypedValue;
import org.apache.calcite.avatica.util.ArrayIteratorCursor;
import org.apache.calcite.avatica.util.Cursor;
import org.apache.calcite.avatica.util.IteratorCursor;
import org.apache.calcite.avatica.util.ListIteratorCursor;
import org.apache.calcite.avatica.util.MapIteratorCursor;
import org.apache.calcite.avatica.util.RecordIteratorCursor;

import com.fasterxml.jackson.annotation.JsonIgnore;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * Basic implementation of {@link Meta}.
 *
 * <p>Each sub-class must implement the two remaining abstract methods,
 * {@link #prepare} and
 * {@link #prepareAndExecute}.
 * It should also override metadata methods such as {@link #getCatalogs(Meta.ConnectionHandle)} and
 * {@link #getTables} for the element types for which it has instances; the
 * default metadata methods return empty collections.
 */
public abstract class MetaImpl implements Meta {
  /** The {@link AvaticaConnection} backing {@code this}. */
  protected final AvaticaConnection connection;
  /** Represents the various states specific to {@link #connection}.
   *
   * <p>Note: this instance is used recursively with {@link #connection}'s getter and setter
   * methods.</p>
   */
  protected final ConnectionPropertiesImpl connProps;

  public MetaImpl(AvaticaConnection connection) {
    this.connection = connection;
    this.connProps = new ConnectionPropertiesImpl();
  }

  /** Uses a {@link org.apache.calcite.avatica.Meta.CursorFactory} to convert
   * an {@link Iterable} into a
   * {@link org.apache.calcite.avatica.util.Cursor}. */
  public static Cursor createCursor(CursorFactory cursorFactory,
      Iterable<Object> iterable) {
    switch (cursorFactory.style) {
    case OBJECT:
      return new IteratorCursor<Object>(iterable.iterator()) {
        protected Getter createGetter(int ordinal) {
          return new ObjectGetter(ordinal);
        }
      };
    case ARRAY:
      @SuppressWarnings("unchecked") final Iterable<Object[]> iterable1 =
          (Iterable<Object[]>) (Iterable) iterable;
      return new ArrayIteratorCursor(iterable1.iterator());
    case RECORD:
      @SuppressWarnings("unchecked") final Class<Object> clazz = cursorFactory.clazz;
      return new RecordIteratorCursor<>(iterable.iterator(), clazz, cursorFactory.fields);
    case LIST:
      @SuppressWarnings("unchecked") final Iterable<List<Object>> iterable2 =
          (Iterable<List<Object>>) (Iterable) iterable;
      return new ListIteratorCursor(iterable2.iterator());
    case MAP:
      @SuppressWarnings("unchecked") final Iterable<Map<String, Object>>
          iterable3 =
          (Iterable<Map<String, Object>>) (Iterable) iterable;
      return new MapIteratorCursor(iterable3.iterator(),
          cursorFactory.fieldNames);
    default:
      throw new AssertionError("unknown style: " + cursorFactory.style);
    }
  }

  public static List<List<Object>> collect(CursorFactory cursorFactory,
      final Iterator<Object> iterator, List<List<Object>> list) {
    final Iterable<Object> iterable = new Iterable<Object>() {
      public Iterator<Object> iterator() {
        return iterator;
      }
    };
    return collect(cursorFactory, iterable, list);
  }

  public static List<List<Object>> collect(CursorFactory cursorFactory,
      Iterable<Object> iterable, final List<List<Object>> list) {
    switch (cursorFactory.style) {
    case OBJECT:
      for (Object o : iterable) {
        list.add(Collections.singletonList(o));
      }
      return list;
    case ARRAY:
      @SuppressWarnings("unchecked") final Iterable<Object[]> iterable1 =
          (Iterable<Object[]>) (Iterable) iterable;
      for (Object[] objects : iterable1) {
        list.add(Arrays.asList(objects));
      }
      return list;
    case RECORD:
      final Field[] fields = cursorFactory.fields.toArray(
          new Field[cursorFactory.fields.size()]);
      for (Object o : iterable) {
        final Object[] objects = new Object[fields.length];
        for (int i = 0; i < fields.length; i++) {
          Field field = fields[i];
          try {
            objects[i] = field.get(o);
          } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
          }
        }
        list.add(Arrays.asList(objects));
      }
      return list;
    case LIST:
      @SuppressWarnings("unchecked") final Iterable<List<Object>> iterable2 =
          (Iterable<List<Object>>) (Iterable) iterable;
      for (List<Object> objects : iterable2) {
        list.add(objects);
      }
      return list;
    case MAP:
      @SuppressWarnings("unchecked") final Iterable<Map<String, Object>>
          iterable3 =
          (Iterable<Map<String, Object>>) (Iterable) iterable;
      for (Map<String, Object> map : iterable3) {
        final List<Object> objects = new ArrayList<Object>();
        for (String fieldName : cursorFactory.fieldNames) {
          objects.add(map.get(fieldName));
        }
        list.add(objects);
      }
      return list;
    default:
      throw new AssertionError("unknown style: " + cursorFactory.style);
    }
  }

  @Override public void openConnection(ConnectionHandle ch, Map<String, String> info) {
    // dummy implementation, connection is already created at this point
  }

  @Override public void closeConnection(ConnectionHandle ch) {
    // TODO: implement
    //
    // lots of Calcite tests break with this simple implementation,
    // requires investigation

//    try {
//      connection.close();
//    } catch (SQLException e) {
//      throw new RuntimeException(e);
//    }
  }

  @Override public ConnectionProperties connectionSync(ConnectionHandle ch,
      ConnectionProperties connProps) {
    this.connProps.merge(connProps);
    this.connProps.setDirty(false);
    return this.connProps;
  }

  public StatementHandle createStatement(ConnectionHandle ch) {
    return new StatementHandle(ch.id, connection.statementCount++, null);
  }

  /** Creates an empty result set. Useful for JDBC metadata methods that are
   * not implemented or which query entities that are not supported (e.g.
   * triggers in Lingual). */
  protected <E> MetaResultSet createEmptyResultSet(final Class<E> clazz) {
    return createResultSet(Collections.<String, Object>emptyMap(),
        fieldMetaData(clazz).columns,
        CursorFactory.deduce(fieldMetaData(clazz).columns, null),
        Frame.EMPTY);
  }

  private static int intForColumnNullable(boolean nullable) {
    return nullable ? DatabaseMetaData.columnNullable : DatabaseMetaData.columnNoNulls;
  }

  public static ColumnMetaData columnMetaData(String name, int index,
      Class<?> type, boolean columnNullable) {
    return columnMetaData(name, index, type, intForColumnNullable(columnNullable));
  }

  public static ColumnMetaData columnMetaData(String name, int index, AvaticaType type,
      boolean columnNullable) {
    return columnMetaData(name, index, type, intForColumnNullable(columnNullable));
  }

  public static ColumnMetaData columnMetaData(String name, int index,
      Class<?> type, int columnNullable) {
    TypeInfo pair = TypeInfo.m.get(type);
    ColumnMetaData.Rep rep =
        ColumnMetaData.Rep.VALUE_MAP.get(type);
    ColumnMetaData.AvaticaType scalarType =
        ColumnMetaData.scalar(pair.sqlType, pair.sqlTypeName, rep);
    return columnMetaData(name, index, scalarType, columnNullable);
  }

  public static ColumnMetaData columnMetaData(String name, int index, AvaticaType type,
      int columnNullable) {
    return new ColumnMetaData(
        index, false, true, false, false,
        columnNullable,
        true, -1, name, name, null,
        0, 0, null, null, type, true, false, false,
        type.columnClassName());
  }

  protected static ColumnMetaData.StructType fieldMetaData(Class<?> clazz) {
    final List<ColumnMetaData> list = new ArrayList<ColumnMetaData>();
    for (Field field : clazz.getFields()) {
      if (Modifier.isPublic(field.getModifiers())
          && !Modifier.isStatic(field.getModifiers())) {
        int columnNullable = getColumnNullability(field);
        list.add(
            columnMetaData(
                AvaticaUtils.camelToUpper(field.getName()),
                list.size(), field.getType(), columnNullable));
      }
    }
    return ColumnMetaData.struct(list);
  }

  protected static int getColumnNullability(Field field) {
    // Check annotations first
    if (field.isAnnotationPresent(ColumnNoNulls.class)) {
      return DatabaseMetaData.columnNoNulls;
    }

    if (field.isAnnotationPresent(ColumnNullable.class)) {
      return DatabaseMetaData.columnNullable;
    }

    if (field.isAnnotationPresent(ColumnNullableUnknown.class)) {
      return DatabaseMetaData.columnNullableUnknown;
    }

    // check the field type to decide if annotated, as a fallback
    if (field.getType().isPrimitive()) {
      return DatabaseMetaData.columnNoNulls;
    }

    return DatabaseMetaData.columnNullable;
  }

  protected MetaResultSet createResultSet(
      Map<String, Object> internalParameters, List<ColumnMetaData> columns,
      CursorFactory cursorFactory, Frame firstFrame) {
    try {
      final AvaticaStatement statement = connection.createStatement();
      final Signature signature =
          new Signature(columns, "", Collections.<AvaticaParameter>emptyList(),
              internalParameters, cursorFactory, Meta.StatementType.SELECT);
      return MetaResultSet.create(connection.id, statement.getId(), true,
          signature, firstFrame);
    } catch (SQLException e) {
      throw new RuntimeException(e);
    }
  }

  /** An object that has a name. */
  public interface Named {
    @JsonIgnore String getName();
  }

  /** Annotation that indicates that a meta field may contain null values. */
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.FIELD)
  public @interface ColumnNullable {
  }

  /** Annotation that indicates that it is unknown whether a meta field may contain
   * null values. */
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.FIELD)
  public @interface ColumnNullableUnknown {
  }

  /** Annotation that indicates that a meta field may not contain null
   * values. */
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.FIELD)
  public @interface ColumnNoNulls {
  }

  /** Metadata describing a column. */
  public static class MetaColumn implements Named {
    public final String tableCat;
    public final String tableSchem;
    @ColumnNoNulls
    public final String tableName;
    @ColumnNoNulls
    public final String columnName;
    public final int dataType;
    @ColumnNoNulls
    public final String typeName;
    public final Integer columnSize;
    @ColumnNullableUnknown
    public final Integer bufferLength = null;
    public final Integer decimalDigits;
    public final Integer numPrecRadix;
    public final int nullable;
    public final String remarks = null;
    public final String columnDef = null;
    @ColumnNullableUnknown
    public final Integer sqlDataType = null;
    @ColumnNullableUnknown
    public final Integer sqlDatetimeSub = null;
    public final Integer charOctetLength;
    public final int ordinalPosition;
    @ColumnNoNulls
    public final String isNullable;
    public final String scopeCatalog = null;
    public final String scopeSchema = null;
    public final String scopeTable = null;
    public final Short sourceDataType = null;
    @ColumnNoNulls
    public final String isAutoincrement = "";
    @ColumnNoNulls
    public final String isGeneratedcolumn = "";

    public MetaColumn(
        String tableCat,
        String tableSchem,
        String tableName,
        String columnName,
        int dataType,
        String typeName,
        Integer columnSize,
        Integer decimalDigits,
        Integer numPrecRadix,
        int nullable,
        Integer charOctetLength,
        int ordinalPosition,
        String isNullable) {
      this.tableCat = tableCat;
      this.tableSchem = tableSchem;
      this.tableName = tableName;
      this.columnName = columnName;
      this.dataType = dataType;
      this.typeName = typeName;
      this.columnSize = columnSize;
      this.decimalDigits = decimalDigits;
      this.numPrecRadix = numPrecRadix;
      this.nullable = nullable;
      this.charOctetLength = charOctetLength;
      this.ordinalPosition = ordinalPosition;
      this.isNullable = isNullable;
    }

    public String getName() {
      return columnName;
    }
  }

  /** Metadata describing a table. */
  public static class MetaTable implements Named {
    public final String tableCat;
    public final String tableSchem;
    @ColumnNoNulls
    public final String tableName;
    @ColumnNoNulls
    public final String tableType;
    public final String remarks = null;
    public final String typeCat = null;
    public final String typeSchem = null;
    public final String typeName = null;
    public final String selfReferencingColName = null;
    public final String refGeneration = null;

    public MetaTable(
        String tableCat,
        String tableSchem,
        String tableName,
        String tableType) {
      this.tableCat = tableCat;
      this.tableSchem = tableSchem;
      this.tableName = tableName;
      this.tableType = tableType;
    }

    public String getName() {
      return tableName;
    }
  }

  /** Metadata describing a schema. */
  public static class MetaSchema implements Named {
    @ColumnNoNulls
    public final String tableSchem;
    public final String tableCatalog;

    public MetaSchema(
        String tableCatalog,
        String tableSchem) {
      this.tableCatalog = tableCatalog;
      this.tableSchem = tableSchem;
    }

    public String getName() {
      return tableSchem;
    }
  }

  /** Metadata describing a catalog. */
  public static class MetaCatalog implements Named {
    @ColumnNoNulls
    public final String tableCat;

    public MetaCatalog(
        String tableCatalog) {
      this.tableCat = tableCatalog;
    }

    public String getName() {
      return tableCat;
    }
  }

  /** Metadata describing a table type. */
  public static class MetaTableType {
    @ColumnNoNulls
    public final String tableType;

    public MetaTableType(String tableType) {
      this.tableType = tableType;
    }
  }

  /** Metadata describing a procedure. */
  public static class MetaProcedure {
    public final String procedureCat;
    public final String procedureSchem;
    @ColumnNoNulls
    public final String procedureName;
    public final String futureUse1 = null;
    public final String futureUse2 = null;
    public final String futureUse3 = null;
    public final String remarks = null;
    public final short procedureType;
    public final String specificName;

    public MetaProcedure(String procedureCat, String procedureSchem, String procedureName,
        short procedureType, String specificName) {
      this.procedureCat = procedureCat;
      this.procedureSchem = procedureSchem;
      this.procedureName = procedureName;
      this.procedureType = procedureType;
      this.specificName = specificName;
    }
  }

  /** Metadata describing a procedure column. */
  public static class MetaProcedureColumn {
    public final String procedureCat;
    public final String procedureSchem;
    @ColumnNoNulls
    public final String procedureName;
    @ColumnNoNulls
    public final String columnName;
    public final short columnType;
    public final int dataType;
    @ColumnNoNulls
    public final String typeName;
    public final Integer precision;
    public final Integer length;
    public final Short scale;
    public final Short radix;
    public final short nullable;
    public final String remarks = null;
    public final String columnDef;
    @ColumnNullableUnknown
    public final Integer sqlDataType = null;
    @ColumnNullableUnknown
    public final Integer sqlDatetimeSub = null;
    public final Integer charOctetLength;
    public final int ordinalPosition;
    @ColumnNoNulls
    public final String isNullable;
    public final String specificName;

    public MetaProcedureColumn(
        String procedureCat,
        String procedureSchem,
        String procedureName,
        String columnName,
        short columnType,
        int dataType,
        String typeName,
        Integer precision,
        Integer length,
        Short scale,
        Short radix,
        short nullable,
        String columnDef,
        Integer charOctetLength,
        int ordinalPosition,
        String isNullable,
        String specificName) {
      this.procedureCat = procedureCat;
      this.procedureSchem = procedureSchem;
      this.procedureName = procedureName;
      this.columnName = columnName;
      this.columnType = columnType;
      this.dataType = dataType;
      this.typeName = typeName;
      this.precision = precision;
      this.length = length;
      this.scale = scale;
      this.radix = radix;
      this.nullable = nullable;
      this.columnDef = columnDef;
      this.charOctetLength = charOctetLength;
      this.ordinalPosition = ordinalPosition;
      this.isNullable = isNullable;
      this.specificName = specificName;
    }
  }

  /** Metadata describing a column privilege. */
  public static class MetaColumnPrivilege {
    public final String tableCat;
    public final String tableSchem;
    @ColumnNoNulls
    public final String tableName;
    @ColumnNoNulls
    public final String columnName;
    public final String grantor;
    @ColumnNoNulls
    public final String grantee;
    @ColumnNoNulls
    public final String privilege;
    public final String isGrantable;

    public MetaColumnPrivilege(
        String tableCat,
        String tableSchem,
        String tableName,
        String columnName,
        String grantor,
        String grantee,
        String privilege,
        String isGrantable) {
      this.tableCat = tableCat;
      this.tableSchem = tableSchem;
      this.tableName = tableName;
      this.columnName = columnName;
      this.grantor = grantor;
      this.grantee = grantee;
      this.privilege = privilege;
      this.isGrantable = isGrantable;
    }
  }

  /** Metadata describing a table privilege. */
  public static class MetaTablePrivilege {
    public final String tableCat;
    public final String tableSchem;
    @ColumnNoNulls
    public final String tableName;

    public final String grantor;
    @ColumnNoNulls
    public final String grantee;
    @ColumnNoNulls
    public final String privilege;
    public final String isGrantable;

    public MetaTablePrivilege(
        String tableCat,
        String tableSchem,
        String tableName,
        String grantor,
        String grantee,
        String privilege,
        String isGrantable) {
      this.tableCat = tableCat;
      this.tableSchem = tableSchem;
      this.tableName = tableName;
      this.grantor = grantor;
      this.grantee = grantee;
      this.privilege = privilege;
      this.isGrantable = isGrantable;
    }
  }

  /** Metadata describing the best identifier for a row. */
  public static class MetaBestRowIdentifier {
    public final short scope;
    @ColumnNoNulls
    public final String columnName;
    public final int dataType;
    @ColumnNoNulls
    public final String typeName;
    public final Integer columnSize;
    @ColumnNullableUnknown
    public final Integer bufferLength = null;
    public final Short decimalDigits;
    public short pseudoColumn;

    public MetaBestRowIdentifier(
        short scope,
        String columnName,
        int dataType,
        String typeName,
        Integer columnSize,
        Short decimalDigits,
        short pseudoColumn) {
      this.scope = scope;
      this.columnName = columnName;
      this.dataType = dataType;
      this.typeName = typeName;
      this.columnSize = columnSize;
      this.decimalDigits = decimalDigits;
      this.pseudoColumn = pseudoColumn;
    }
  }

  /** Metadata describing a version column. */
  public static class MetaVersionColumn {
    @ColumnNullableUnknown
    public final Short scope;
    @ColumnNoNulls
    public final String columnName;
    public final int dataType;
    @ColumnNoNulls
    public final String typeName;
    public final Integer columnSize;
    public final Integer bufferLength;
    public final Short decimalDigits;
    public final short pseudoColumn;

    MetaVersionColumn(
        Short scope,
        String columnName,
        int dataType,
        String typeName,
        Integer columnSize,
        Integer bufferLength,
        Short decimalDigits,
        short pseudoColumn) {
      this.scope = scope;
      this.columnName = columnName;
      this.dataType = dataType;
      this.typeName = typeName;
      this.columnSize = columnSize;
      this.bufferLength = bufferLength;
      this.decimalDigits = decimalDigits;
      this.pseudoColumn = pseudoColumn;
    }
  }

  /** Metadata describing a primary key. */
  public static class MetaPrimaryKey {
    public final String tableCat;
    public final String tableSchem;
    @ColumnNoNulls
    public final String tableName;
    @ColumnNoNulls
    public final String columnName;
    public final short keySeq;
    public final String pkName;

    MetaPrimaryKey(
        String tableCat,
        String tableSchem,
        String tableName,
        String columnName,
        short keySeq,
        String pkName) {
      this.tableCat = tableCat;
      this.tableSchem = tableSchem;
      this.tableName = tableName;
      this.columnName = columnName;
      this.keySeq = keySeq;
      this.pkName = pkName;
    }
  }

  /** Metadata describing an imported key. */
  public static class MetaImportedKey {
    public final String pktableCat;
    public final String pktableSchem;
    @ColumnNoNulls
    public final String pktableName;
    @ColumnNoNulls
    public final String pkcolumnName;
    public final String fktableCat;
    public final String fktableSchem;
    @ColumnNoNulls
    public final String fktableName;
    @ColumnNoNulls
    public final String fkcolumnName;
    public final short keySeq;
    public final short updateRule;
    public final short deleteRule;
    public final String fkName;
    public final String pkName;
    public final short deferability;

    public MetaImportedKey(
        String pktableCat,
        String pktableSchem,
        String pktableName,
        String pkcolumnName,
        String fktableCat,
        String fktableSchem,
        String fktableName,
        String fkcolumnName,
        short keySeq,
        short updateRule,
        short deleteRule,
        String fkName,
        String pkName,
        short deferability) {
      this.pktableCat = pktableCat;
      this.pktableSchem = pktableSchem;
      this.pktableName = pktableName;
      this.pkcolumnName = pkcolumnName;
      this.fktableCat = fktableCat;
      this.fktableSchem = fktableSchem;
      this.fktableName = fktableName;
      this.fkcolumnName = fkcolumnName;
      this.keySeq = keySeq;
      this.updateRule = updateRule;
      this.deleteRule = deleteRule;
      this.fkName = fkName;
      this.pkName = pkName;
      this.deferability = deferability;
    }
  }

  /** Metadata describing an exported key. */
  public static class MetaExportedKey {
    public final String pktableCat;
    public final String pktableSchem;
    @ColumnNoNulls
    public final String pktableName;
    @ColumnNoNulls
    public final String pkcolumnName;
    public final String fktableCat;
    public final String fktableSchem;
    @ColumnNoNulls
    public final String fktableName;
    @ColumnNoNulls
    public final String fkcolumnName;
    public final short keySeq;
    public final short updateRule;
    public final short deleteRule;
    public final String fkName;
    public final String pkName;
    public final short deferability;

    public MetaExportedKey(
        String pktableCat,
        String pktableSchem,
        String pktableName,
        String pkcolumnName,
        String fktableCat,
        String fktableSchem,
        String fktableName,
        String fkcolumnName,
        short keySeq,
        short updateRule,
        short deleteRule,
        String fkName,
        String pkName,
        short deferability) {
      this.pktableCat = pktableCat;
      this.pktableSchem = pktableSchem;
      this.pktableName = pktableName;
      this.pkcolumnName = pkcolumnName;
      this.fktableCat = fktableCat;
      this.fktableSchem = fktableSchem;
      this.fktableName = fktableName;
      this.fkcolumnName = fkcolumnName;
      this.keySeq = keySeq;
      this.updateRule = updateRule;
      this.deleteRule = deleteRule;
      this.fkName = fkName;
      this.pkName = pkName;
      this.deferability = deferability;
    }
  }

  /** Metadata describing a cross reference. */
  public static class MetaCrossReference {
    public final String pktableCat;
    public final String pktableSchem;
    @ColumnNoNulls
    public final String pktableName;
    @ColumnNoNulls
    public final String pkcolumnName;
    public final String fktableCat;
    public final String fktableSchem;
    @ColumnNoNulls
    public final String fktableName;
    @ColumnNoNulls
    public final String fkcolumnName;
    public final short keySeq;
    public final short updateRule;
    public final short deleteRule;
    public final String fkName;
    public final String pkName;
    public final short deferability;

    public MetaCrossReference(
        String pktableCat,
        String pktableSchem,
        String pktableName,
        String pkcolumnName,
        String fktableCat,
        String fktableSchem,
        String fktableName,
        String fkcolumnName,
        short keySeq,
        short updateRule,
        short deleteRule,
        String fkName,
        String pkName,
        short deferability) {
      this.pktableCat = pktableCat;
      this.pktableSchem = pktableSchem;
      this.pktableName = pktableName;
      this.pkcolumnName = pkcolumnName;
      this.fktableCat = fktableCat;
      this.fktableSchem = fktableSchem;
      this.fktableName = fktableName;
      this.fkcolumnName = fkcolumnName;
      this.keySeq = keySeq;
      this.updateRule = updateRule;
      this.deleteRule = deleteRule;
      this.fkName = fkName;
      this.pkName = pkName;
      this.deferability = deferability;
    }
  }

  /** Metadata describing type info. */
  public static class MetaTypeInfo implements Named {
    @ColumnNoNulls
    public final String typeName;
    public final int dataType;
    public final Integer precision;
    public final String literalPrefix;
    public final String literalSuffix;
    //TODO: Add create parameter for type on DDL
    public final String createParams = null;
    public final short nullable;
    public final boolean caseSensitive;
    public final short searchable;
    public final boolean unsignedAttribute;
    public final boolean fixedPrecScale;
    public final boolean autoIncrement;
    public final String localTypeName;
    public final Short minimumScale;
    public final Short maximumScale;
    @ColumnNullableUnknown
    public final Integer sqlDataType = null;
    @ColumnNullableUnknown
    public final Integer sqlDatetimeSub = null;
    public final Integer numPrecRadix; //nullable int

    public MetaTypeInfo(
        String typeName,
        int dataType,
        Integer precision,
        String literalPrefix,
        String literalSuffix,
        short nullable,
        boolean caseSensitive,
        short searchable,
        boolean unsignedAttribute,
        boolean fixedPrecScale,
        boolean autoIncrement,
        Short minimumScale,
        Short maximumScale,
        Integer numPrecRadix) {
      this.typeName = typeName;
      this.dataType = dataType;
      this.precision = precision;
      this.literalPrefix = literalPrefix;
      this.literalSuffix = literalSuffix;
      this.nullable = nullable;
      this.caseSensitive = caseSensitive;
      this.searchable = searchable;
      this.unsignedAttribute = unsignedAttribute;
      this.fixedPrecScale = fixedPrecScale;
      this.autoIncrement = autoIncrement;
      this.localTypeName = typeName;
      this.minimumScale = minimumScale;
      this.maximumScale = maximumScale;
      this.numPrecRadix = numPrecRadix == 0 ? null : numPrecRadix;
    }

    public String getName() {
      return typeName;
    }
  }

  /** Metadata describing index info. */
  public static class MetaIndexInfo {
    public final String tableCat;
    public final String tableSchem;
    @ColumnNoNulls
    public final String tableName;
    public final boolean nonUnique;
    public final String indexQualifier;
    public final String indexName;
    public final short type;
    public final short ordinalPosition;
    public final String columnName;
    public final String ascOrDesc;
    public final long cardinality;
    public final long pages;
    public final String filterCondition;

    public MetaIndexInfo(
        String tableCat,
        String tableSchem,
        String tableName,
        boolean nonUnique,
        String indexQualifier,
        String indexName,
        short type,
        short ordinalPosition,
        String columnName,
        String ascOrDesc,
        long cardinality,
        long pages,
        String filterCondition) {
      this.tableCat = tableCat;
      this.tableSchem = tableSchem;
      this.tableName = tableName;
      this.nonUnique = nonUnique;
      this.indexQualifier = indexQualifier;
      this.indexName = indexName;
      this.type = type;
      this.ordinalPosition = ordinalPosition;
      this.columnName = columnName;
      this.ascOrDesc = ascOrDesc;
      this.cardinality = cardinality;
      this.pages = pages;
      this.filterCondition = filterCondition;
    }
  }

  /** Metadata describing a user-defined type. */
  public static class MetaUdt {
    public final String typeCat;
    public final String typeSchem;
    @ColumnNoNulls
    public final String typeName;
    @ColumnNoNulls
    public final String className;
    public final int dataType;
    public final String remarks = null;
    public final Short baseType;

    public MetaUdt(
        String typeCat,
        String typeSchem,
        String typeName,
        String className,
        int dataType,
        Short baseType) {
      this.typeCat = typeCat;
      this.typeSchem = typeSchem;
      this.typeName = typeName;
      this.className = className;
      this.dataType = dataType;
      this.baseType = baseType;
    }
  }

  /** Metadata describing a super-type. */
  public static class MetaSuperType {
    public final String typeCat;
    public final String typeSchem;
    @ColumnNoNulls
    public final String typeName;
    public final String supertypeCat;
    public final String supertypeSchem;
    @ColumnNoNulls
    public final String supertypeName;

    public MetaSuperType(
        String typeCat,
        String typeSchem,
        String typeName,
        String supertypeCat,
        String supertypeSchem,
        String supertypeName) {
      this.typeCat = typeCat;
      this.typeSchem = typeSchem;
      this.typeName = typeName;
      this.supertypeCat = supertypeCat;
      this.supertypeSchem = supertypeSchem;
      this.supertypeName = supertypeName;
    }
  }

  /** Metadata describing an attribute. */
  public static class MetaAttribute {
    public final String typeCat;
    public final String typeSchem;
    @ColumnNoNulls
    public final String typeName;
    @ColumnNoNulls
    public final String attrName;
    public final int dataType;
    @ColumnNoNulls
    public String attrTypeName;
    public final Integer attrSize;
    public final Integer decimalDigits;
    public final Integer numPrecRadix;
    public final int nullable;
    public final String remarks = null;
    public final String attrDef = null;
    @ColumnNullableUnknown
    public final Integer sqlDataType = null;
    @ColumnNullableUnknown
    public final Integer sqlDatetimeSub = null;
    public final Integer charOctetLength;
    public final int ordinalPosition;
    @ColumnNoNulls
    public final String isNullable;
    public final String scopeCatalog = null;
    public final String scopeSchema = null;
    public final String scopeTable = null;
    public final Short sourceDataType = null;

    public MetaAttribute(
        String typeCat,
        String typeSchem,
        String typeName,
        String attrName,
        int dataType,
        String attrTypeName,
        Integer attrSize,
        Integer decimalDigits,
        Integer numPrecRadix,
        int nullable,
        Integer charOctetLength,
        int ordinalPosition,
        String isNullable) {
      this.typeCat = typeCat;
      this.typeSchem = typeSchem;
      this.typeName = typeName;
      this.attrName = attrName;
      this.dataType = dataType;
      this.attrTypeName = attrTypeName;
      this.attrSize = attrSize;
      this.decimalDigits = decimalDigits;
      this.numPrecRadix = numPrecRadix;
      this.nullable = nullable;
      this.charOctetLength = charOctetLength;
      this.ordinalPosition = ordinalPosition;
      this.isNullable = isNullable;
    }
  }

  /** Metadata describing a client info property. */
  public static class MetaClientInfoProperty {
    @ColumnNoNulls
    public final String name;
    public final int maxLen;
    public final String defaultValue;
    public final String description;

    public MetaClientInfoProperty(
        String name,
        int maxLen,
        String defaultValue,
        String description) {
      this.name = name;
      this.maxLen = maxLen;
      this.defaultValue = defaultValue;
      this.description = description;
    }
  }

  /** Metadata describing a function. */
  public static class MetaFunction {
    public final String functionCat;
    public final String functionSchem;
    @ColumnNoNulls
    public final String functionName;
    public final String remarks = null;
    public final short functionType;
    public final String specificName;

    public MetaFunction(
        String functionCat,
        String functionSchem,
        String functionName,
        short functionType,
        String specificName) {
      this.functionCat = functionCat;
      this.functionSchem = functionSchem;
      this.functionName = functionName;
      this.functionType = functionType;
      this.specificName = specificName;
    }
  }

  /** Metadata describing a function column. */
  public static class MetaFunctionColumn {
    public final String functionCat;
    public final String functionSchem;
    @ColumnNoNulls
    public final String functionName;
    @ColumnNoNulls
    public final String columnName;
    public final short columnType;
    public final int dataType;
    @ColumnNoNulls
    public final String typeName;
    public final Integer precision;
    public final Integer length;
    public final Short scale;
    public final Short radix;
    public final short nullable;
    public final String remarks = null;
    public final Integer charOctetLength;
    public final int ordinalPosition;
    @ColumnNoNulls
    public final String isNullable;
    public final String specificName;

    public MetaFunctionColumn(
        String functionCat,
        String functionSchem,
        String functionName,
        String columnName,
        short columnType,
        int dataType,
        String typeName,
        Integer precision,
        Integer length,
        Short scale,
        Short radix,
        short nullable,
        Integer charOctetLength,
        int ordinalPosition,
        String isNullable,
        String specificName) {
      this.functionCat = functionCat;
      this.functionSchem = functionSchem;
      this.functionName = functionName;
      this.columnName = columnName;
      this.columnType = columnType;
      this.dataType = dataType;
      this.typeName = typeName;
      this.precision = precision;
      this.length = length;
      this.scale = scale;
      this.radix = radix;
      this.nullable = nullable;
      this.charOctetLength = charOctetLength;
      this.ordinalPosition = ordinalPosition;
      this.isNullable = isNullable;
      this.specificName = specificName;
    }
  }

  /** Metadata describing a pseudo column. */
  public static class MetaPseudoColumn {
    public final String tableCat;
    public final String tableSchem;
    @ColumnNoNulls
    public final String tableName;
    @ColumnNoNulls
    public final String columnName;
    public final int dataType;
    public final Integer columnSize;
    public final Integer decimalDigits;
    public final Integer numPrecRadix;
    @ColumnNoNulls
    public final String columnUsage;
    public final String remarks = null;
    public final Integer charOctetLength;
    @ColumnNoNulls
    public final String isNullable;

    public MetaPseudoColumn(
        String tableCat,
        String tableSchem,
        String tableName,
        String columnName,
        int dataType,
        Integer columnSize,
        Integer decimalDigits,
        Integer numPrecRadix,
        String columnUsage,
        Integer charOctetLength,
        String isNullable) {
      this.tableCat = tableCat;
      this.tableSchem = tableSchem;
      this.tableName = tableName;
      this.columnName = columnName;
      this.dataType = dataType;
      this.columnSize = columnSize;
      this.decimalDigits = decimalDigits;
      this.numPrecRadix = numPrecRadix;
      this.columnUsage = columnUsage;
      this.charOctetLength = charOctetLength;
      this.isNullable = isNullable;
    }
  }

  /** Metadata describing a super-table. */
  public static class MetaSuperTable {
    public final String tableCat;
    public final String tableSchem;
    @ColumnNoNulls
    public final String tableName;
    @ColumnNoNulls
    public final String supertableName;

    public MetaSuperTable(
        String tableCat,
        String tableSchem,
        String tableName,
        String supertableName) {
      this.tableCat = tableCat;
      this.tableSchem = tableSchem;
      this.tableName = tableName;
      this.supertableName = supertableName;
    }
  }

  public Map<DatabaseProperty, Object> getDatabaseProperties(ConnectionHandle ch) {
    return Collections.emptyMap();
  }

  public MetaResultSet getTables(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat tableNamePattern,
      List<String> typeList) {
    return createEmptyResultSet(MetaTable.class);
  }

  public MetaResultSet getColumns(ConnectionHandle ch, String catalog,
      Pat schemaPattern,
      Pat tableNamePattern,
      Pat columnNamePattern) {
    return createEmptyResultSet(MetaColumn.class);
  }

  public MetaResultSet getSchemas(ConnectionHandle ch, String catalog, Pat schemaPattern) {
    return createEmptyResultSet(MetaSchema.class);
  }

  public MetaResultSet getCatalogs(ConnectionHandle ch) {
    return createEmptyResultSet(MetaCatalog.class);
  }

  public MetaResultSet getTableTypes(ConnectionHandle ch) {
    return createEmptyResultSet(MetaTableType.class);
  }

  public MetaResultSet getProcedures(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat procedureNamePattern) {
    return createEmptyResultSet(MetaProcedure.class);
  }

  public MetaResultSet getProcedureColumns(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat procedureNamePattern,
      Pat columnNamePattern) {
    return createEmptyResultSet(MetaProcedureColumn.class);
  }

  public MetaResultSet getColumnPrivileges(ConnectionHandle ch,
      String catalog,
      String schema,
      String table,
      Pat columnNamePattern) {
    return createEmptyResultSet(MetaColumnPrivilege.class);
  }

  public MetaResultSet getTablePrivileges(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat tableNamePattern) {
    return createEmptyResultSet(MetaTablePrivilege.class);
  }

  public MetaResultSet getBestRowIdentifier(ConnectionHandle ch,
      String catalog,
      String schema,
      String table,
      int scope,
      boolean nullable) {
    return createEmptyResultSet(MetaBestRowIdentifier.class);
  }

  public MetaResultSet getVersionColumns(ConnectionHandle ch,
      String catalog,
      String schema,
      String table) {
    return createEmptyResultSet(MetaVersionColumn.class);
  }

  public MetaResultSet getPrimaryKeys(ConnectionHandle ch,
      String catalog,
      String schema,
      String table) {
    return createEmptyResultSet(MetaPrimaryKey.class);
  }

  public MetaResultSet getImportedKeys(ConnectionHandle ch,
      String catalog,
      String schema,
      String table) {
    return createEmptyResultSet(MetaImportedKey.class);
  }

  public MetaResultSet getExportedKeys(ConnectionHandle ch,
      String catalog,
      String schema,
      String table) {
    return createEmptyResultSet(MetaExportedKey.class);
  }

  public MetaResultSet getCrossReference(ConnectionHandle ch,
      String parentCatalog,
      String parentSchema,
      String parentTable,
      String foreignCatalog,
      String foreignSchema,
      String foreignTable) {
    return createEmptyResultSet(MetaCrossReference.class);
  }

  public MetaResultSet getTypeInfo(ConnectionHandle ch) {
    return createEmptyResultSet(MetaTypeInfo.class);
  }

  public MetaResultSet getIndexInfo(ConnectionHandle ch,
      String catalog,
      String schema,
      String table,
      boolean unique,
      boolean approximate) {
    return createEmptyResultSet(MetaIndexInfo.class);
  }

  public MetaResultSet getUDTs(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat typeNamePattern,
      int[] types) {
    return createEmptyResultSet(MetaUdt.class);
  }

  public MetaResultSet getSuperTypes(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat typeNamePattern) {
    return createEmptyResultSet(MetaSuperType.class);
  }

  public MetaResultSet getSuperTables(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat tableNamePattern) {
    return createEmptyResultSet(MetaSuperTable.class);
  }

  public MetaResultSet getAttributes(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat typeNamePattern,
      Pat attributeNamePattern) {
    return createEmptyResultSet(MetaAttribute.class);
  }

  public MetaResultSet getClientInfoProperties(ConnectionHandle ch) {
    return createEmptyResultSet(MetaClientInfoProperty.class);
  }

  public MetaResultSet getFunctions(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat functionNamePattern) {
    return createEmptyResultSet(MetaFunction.class);
  }

  public MetaResultSet getFunctionColumns(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat functionNamePattern,
      Pat columnNamePattern) {
    return createEmptyResultSet(MetaFunctionColumn.class);
  }

  public MetaResultSet getPseudoColumns(ConnectionHandle ch,
      String catalog,
      Pat schemaPattern,
      Pat tableNamePattern,
      Pat columnNamePattern) {
    return createEmptyResultSet(MetaPseudoColumn.class);
  }

  @Override public Iterable<Object> createIterable(StatementHandle handle, QueryState state,
      Signature signature, List<TypedValue> parameterValues, Frame firstFrame) {
    // `parameterValues` is intentionally unusued (in method signature for historic reasons)
    // Left to preserve API compatibility with Calcite
    if (firstFrame != null && firstFrame.done) {
      return firstFrame.rows;
    }
    AvaticaStatement stmt;
    try {
      stmt = connection.lookupStatement(handle);
    } catch (SQLException e) {
      throw new RuntimeException(e);
    }
    return new FetchIterable(stmt, state, firstFrame);
  }

  public Frame fetch(AvaticaStatement stmt, List<TypedValue> parameterValues,
      long offset, int fetchMaxRowCount) throws NoSuchStatementException, MissingResultsException {
    return null;
  }

  /** Information about a type. */
  private static class TypeInfo {
    private static Map<Class<?>, TypeInfo> m =
        new HashMap<Class<?>, TypeInfo>();
    static {
      put(boolean.class, Types.BOOLEAN, "BOOLEAN");
      put(Boolean.class, Types.BOOLEAN, "BOOLEAN");
      put(byte.class, Types.TINYINT, "TINYINT");
      put(Byte.class, Types.TINYINT, "TINYINT");
      put(short.class, Types.SMALLINT, "SMALLINT");
      put(Short.class, Types.SMALLINT, "SMALLINT");
      put(int.class, Types.INTEGER, "INTEGER");
      put(Integer.class, Types.INTEGER, "INTEGER");
      put(long.class, Types.BIGINT, "BIGINT");
      put(Long.class, Types.BIGINT, "BIGINT");
      put(float.class, Types.FLOAT, "FLOAT");
      put(Float.class, Types.FLOAT, "FLOAT");
      put(double.class, Types.DOUBLE, "DOUBLE");
      put(Double.class, Types.DOUBLE, "DOUBLE");
      put(String.class, Types.VARCHAR, "VARCHAR");
      put(java.sql.Date.class, Types.DATE, "DATE");
      put(Time.class, Types.TIME, "TIME");
      put(Timestamp.class, Types.TIMESTAMP, "TIMESTAMP");
    }

    private final int sqlType;
    private final String sqlTypeName;

    private TypeInfo(int sqlType, String sqlTypeName) {
      this.sqlType = sqlType;
      this.sqlTypeName = sqlTypeName;
    }

    static void put(Class<?> clazz, int sqlType, String sqlTypeName) {
      m.put(clazz, new TypeInfo(sqlType, sqlTypeName));
    }
  }

  /** Iterator that never returns any elements. */
  private static class EmptyIterator implements Iterator<Object> {
    public static final Iterator<Object> INSTANCE = new EmptyIterator();

    public void remove() {
      throw new UnsupportedOperationException();
    }

    public boolean hasNext() {
      return false;
    }

    public Object next() {
      throw new NoSuchElementException();
    }
  }

  /** Iterable that yields an iterator over rows coming from a sequence of
   * {@link Meta.Frame}s. */
  private class FetchIterable implements Iterable<Object> {
    private final AvaticaStatement stmt;
    private final QueryState state;
    private final Frame firstFrame;

    private FetchIterable(AvaticaStatement stmt, QueryState state, Frame firstFrame) {
      this.stmt = stmt;
      this.state = state;
      this.firstFrame = firstFrame;
    }

    public Iterator<Object> iterator() {
      return new FetchIterator(stmt, state, firstFrame);
    }
  }

  /** Iterator over rows coming from a sequence of {@link Meta.Frame}s. */
  private class FetchIterator implements Iterator<Object> {
    private final AvaticaStatement stmt;
    private final QueryState state;
    private Frame frame;
    private Iterator<Object> rows;
    private long currentOffset = 0;

    private FetchIterator(AvaticaStatement stmt, QueryState state, Frame firstFrame) {
      this.stmt = stmt;
      this.state = state;
      if (firstFrame == null) {
        frame = Frame.MORE;
        rows = EmptyIterator.INSTANCE;
      } else {
        frame = firstFrame;
        rows = firstFrame.rows.iterator();
      }
      moveNext();
    }

    public void remove() {
      throw new UnsupportedOperationException("remove");
    }

    public boolean hasNext() {
      return rows != null;
    }

    public Object next() {
      if (rows == null) {
        throw new NoSuchElementException();
      }
      final Object o = rows.next();
      currentOffset++;
      moveNext();
      return o;
    }

    private void moveNext() {
      for (;;) {
        if (rows.hasNext()) {
          break;
        }
        if (frame.done) {
          rows = null;
          break;
        }
        try {
          // currentOffset updated after element is read from `rows` iterator
          frame = fetch(stmt.handle, currentOffset, AvaticaStatement.DEFAULT_FETCH_SIZE);
        } catch (NoSuchStatementException e) {
          resetStatement();
          // re-fetch the batch where we left off
          continue;
        } catch (MissingResultsException e) {
          try {
            // We saw the statement, but it didnt' have a resultset initialized. So, reset it.
            if (!stmt.syncResults(state, currentOffset)) {
              // This returned false, so there aren't actually any more results to iterate over
              frame = null;
              rows = null;
              break;
            }
            // syncResults returning true means we need to fetch those results
          } catch (NoSuchStatementException e1) {
            // Tried to reset the result set, but lost the statement, save a loop before retrying.
            resetStatement();
            // Will just loop back around to a MissingResultsException, but w/e recursion
          }
          // Kick back to the top to try to fetch again (in both branches)
          continue;
        }
        if (frame == null) {
          rows = null;
          break;
        }
        // It is valid for rows to be empty, so we go around the loop again to
        // check
        rows = frame.rows.iterator();
      }
    }

    private void resetStatement() {
      // Defer to the statement to reset itself
      stmt.resetStatement();
    }
  }

  /** Returns whether a list of parameter values has any null elements. */
  public static boolean checkParameterValueHasNull(List<TypedValue> parameterValues) {
    for (TypedValue x : parameterValues) {
      if (x == null) {
        return true;
      }
    }
    return false;
  }
}

// End MetaImpl.java
