AdbcStatusCode SqliteConnectionGetColumnsImpl()

in c/driver/sqlite/sqlite.c [331:437]


AdbcStatusCode SqliteConnectionGetColumnsImpl(
    struct SqliteConnection* conn, const char* table_name, const char* column_name,
    struct ArrowArray* table_columns_col, sqlite3_stmt* stmt, struct AdbcError* error) {
  struct ArrowArray* table_columns_items = table_columns_col->children[0];
  struct ArrowArray* column_name_col = table_columns_items->children[0];
  struct ArrowArray* ordinal_position_col = table_columns_items->children[1];
  struct ArrowArray* remarks_col = table_columns_items->children[2];
  struct ArrowArray* xdbc_data_type_col = table_columns_items->children[3];
  struct ArrowArray* xdbc_type_name_col = table_columns_items->children[4];
  struct ArrowArray* xdbc_column_size_col = table_columns_items->children[5];
  struct ArrowArray* xdbc_decimal_digits_col = table_columns_items->children[6];
  struct ArrowArray* xdbc_num_prec_radix_col = table_columns_items->children[7];
  struct ArrowArray* xdbc_nullable_col = table_columns_items->children[8];
  struct ArrowArray* xdbc_column_def_col = table_columns_items->children[9];
  struct ArrowArray* xdbc_sql_data_type_col = table_columns_items->children[10];
  struct ArrowArray* xdbc_datetime_sub_col = table_columns_items->children[11];
  struct ArrowArray* xdbc_char_octet_length_col = table_columns_items->children[12];
  struct ArrowArray* xdbc_is_nullable_col = table_columns_items->children[13];
  struct ArrowArray* xdbc_scope_catalog_col = table_columns_items->children[14];
  struct ArrowArray* xdbc_scope_schema_col = table_columns_items->children[15];
  struct ArrowArray* xdbc_scope_table_col = table_columns_items->children[16];
  struct ArrowArray* xdbc_is_autoincrement_col = table_columns_items->children[17];
  struct ArrowArray* xdbc_is_generatedcolumn_col = table_columns_items->children[18];

  int rc = sqlite3_reset(stmt);
  RAISE(INTERNAL, rc == SQLITE_OK, sqlite3_errmsg(conn->conn), error);

  rc = sqlite3_bind_text64(stmt, 1, table_name, strlen(table_name), SQLITE_STATIC,
                           SQLITE_UTF8);
  RAISE(INTERNAL, rc == SQLITE_OK, sqlite3_errmsg(conn->conn), error);

  if (column_name) {
    rc = sqlite3_bind_text64(stmt, 2, column_name, strlen(column_name), SQLITE_STATIC,
                             SQLITE_UTF8);
  } else {
    rc = sqlite3_bind_text64(stmt, 2, "%", 1, SQLITE_STATIC, SQLITE_UTF8);
  }
  RAISE(INTERNAL, rc == SQLITE_OK, sqlite3_errmsg(conn->conn), error);

  while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
    const char* col_name = (const char*)sqlite3_column_text(stmt, 1);
    struct ArrowStringView str = {.data = col_name,
                                  .size_bytes = sqlite3_column_bytes(stmt, 1)};
    CHECK_NA(INTERNAL, ArrowArrayAppendString(column_name_col, str), error);

    const int32_t col_cid = sqlite3_column_int(stmt, 0);
    CHECK_NA(INTERNAL, ArrowArrayAppendInt(ordinal_position_col, col_cid + 1), error);
    CHECK_NA(INTERNAL, ArrowArrayAppendNull(remarks_col, 1), error);

    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_data_type_col, 1), error);

    const char* col_type = (const char*)sqlite3_column_text(stmt, 2);
    if (col_type) {
      str.data = col_type;
      str.size_bytes = sqlite3_column_bytes(stmt, 2);
      CHECK_NA(INTERNAL, ArrowArrayAppendString(xdbc_type_name_col, str), error);
    } else {
      CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_type_name_col, 1), error);
    }

    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_column_size_col, 1), error);
    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_decimal_digits_col, 1), error);
    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_num_prec_radix_col, 1), error);

    const int32_t col_notnull = sqlite3_column_int(stmt, 3);
    if (col_notnull == 0) {
      // JDBC columnNullable == 1
      CHECK_NA(INTERNAL, ArrowArrayAppendInt(xdbc_nullable_col, 1), error);
    } else {
      // JDBC columnNoNulls == 0
      CHECK_NA(INTERNAL, ArrowArrayAppendInt(xdbc_nullable_col, 0), error);
    }

    const char* col_def = (const char*)sqlite3_column_text(stmt, 4);
    if (col_def) {
      str.data = col_def;
      str.size_bytes = sqlite3_column_bytes(stmt, 4);
      CHECK_NA(INTERNAL, ArrowArrayAppendString(xdbc_column_def_col, str), error);
    } else {
      CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_column_def_col, 1), error);
    }

    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_sql_data_type_col, 1), error);
    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_datetime_sub_col, 1), error);
    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_char_octet_length_col, 1), error);

    if (col_notnull == 0) {
      str.data = "YES";
      str.size_bytes = 3;
    } else {
      str.data = "NO";
      str.size_bytes = 2;
    }
    CHECK_NA(INTERNAL, ArrowArrayAppendString(xdbc_is_nullable_col, str), error);

    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_scope_catalog_col, 1), error);
    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_scope_schema_col, 1), error);
    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_scope_table_col, 1), error);
    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_is_autoincrement_col, 1), error);
    CHECK_NA(INTERNAL, ArrowArrayAppendNull(xdbc_is_generatedcolumn_col, 1), error);

    CHECK_NA(INTERNAL, ArrowArrayFinishElement(table_columns_items), error);
  }
  RAISE(INTERNAL, rc == SQLITE_DONE, sqlite3_errmsg(conn->conn), error);

  return ADBC_STATUS_OK;
}