lidavidm commented on code in PR #196:
URL: https://github.com/apache/arrow-adbc/pull/196#discussion_r1033649378


##########
c/driver/sqlite/statement_reader.c:
##########
@@ -0,0 +1,832 @@
+// 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.
+
+#include "statement_reader.h"
+
+#include <inttypes.h>
+#include <math.h>
+#include <stdio.h>
+
+#include <nanoarrow.h>
+#include <sqlite3.h>
+
+#include "utils.h"
+
+AdbcStatusCode AdbcSqliteBinderSet(struct AdbcSqliteBinder* binder,
+                                   struct AdbcError* error) {
+  int rc = binder->params.get_schema(&binder->params, &binder->schema);
+  if (rc != 0) {
+    const char* message = binder->params.get_last_error(&binder->params);
+    if (!message) message = "(unknown error)";
+    SetError(error, "Failed to get parameter schema: (%d) %s: %s", rc, 
strerror(rc),
+             message);
+    return ADBC_STATUS_INVALID_ARGUMENT;
+  }
+
+  struct ArrowError arrow_error = {0};
+  rc = ArrowArrayViewInitFromSchema(&binder->batch, &binder->schema, 
&arrow_error);
+  if (rc != 0) {
+    SetError(error, "Failed to initialize array view: (%d) %s: %s", rc, 
strerror(rc),
+             arrow_error.message);
+    return ADBC_STATUS_INVALID_ARGUMENT;
+  }
+
+  if (binder->batch.storage_type != NANOARROW_TYPE_STRUCT) {
+    SetError(error, "Bind parameters do not have root type STRUCT");
+    return ADBC_STATUS_INVALID_ARGUMENT;
+  }
+
+  binder->types =
+      (enum ArrowType*)malloc(binder->schema.n_children * sizeof(enum 
ArrowType));
+
+  struct ArrowSchemaView view = {0};
+  for (int i = 0; i < binder->schema.n_children; i++) {
+    rc = ArrowSchemaViewInit(&view, binder->schema.children[i], &arrow_error);
+    if (rc != 0) {
+      SetError(error, "Failed to parse schema for column %d: %s (%d): %s", i,
+               strerror(rc), rc, arrow_error.message);
+      return ADBC_STATUS_INVALID_ARGUMENT;
+    }
+
+    if (view.data_type == NANOARROW_TYPE_UNINITIALIZED) {
+      SetError(error, "Column %d has UNINITIALIZED type", i);
+      return ADBC_STATUS_INTERNAL;
+    }
+    binder->types[i] = view.data_type;
+  }
+
+  return ADBC_STATUS_OK;
+}
+
+AdbcStatusCode AdbcSqliteBinderSetArray(struct AdbcSqliteBinder* binder,
+                                        struct ArrowArray* values,
+                                        struct ArrowSchema* schema,
+                                        struct AdbcError* error) {
+  AdbcSqliteBinderRelease(binder);
+  AdbcStatusCode status = BatchToArrayStream(values, schema, &binder->params, 
error);
+  if (status != ADBC_STATUS_OK) return status;
+  return AdbcSqliteBinderSet(binder, error);
+}  // NOLINT(whitespace/indent)
+AdbcStatusCode AdbcSqliteBinderSetArrayStream(struct AdbcSqliteBinder* binder,
+                                              struct ArrowArrayStream* values,
+                                              struct AdbcError* error) {
+  AdbcSqliteBinderRelease(binder);
+  binder->params = *values;
+  memset(values, 0, sizeof(*values));
+  return AdbcSqliteBinderSet(binder, error);
+}
+AdbcStatusCode AdbcSqliteBinderBindNext(struct AdbcSqliteBinder* binder, 
sqlite3* conn,
+                                        sqlite3_stmt* stmt, char* finished,
+                                        struct AdbcError* error) {
+  struct ArrowError arrow_error = {0};
+  int rc = 0;
+  while (!binder->array.release || binder->next_row >= binder->array.length) {
+    if (binder->array.release) {
+      ArrowArrayViewReset(&binder->batch);
+      binder->array.release(&binder->array);
+
+      rc = ArrowArrayViewInitFromSchema(&binder->batch, &binder->schema, 
&arrow_error);
+      if (rc != 0) {
+        SetError(error, "Failed to initialize array view: (%d) %s: %s", rc, 
strerror(rc),
+                 arrow_error.message);
+        return ADBC_STATUS_INTERNAL;
+      }
+    }
+
+    rc = binder->params.get_next(&binder->params, &binder->array);
+    if (rc != 0) {
+      const char* message = binder->params.get_last_error(&binder->params);
+      if (!message) message = "(unknown error)";
+      SetError(error, "Failed to get next parameter batch: (%d) %s: %s", rc, 
strerror(rc),
+               message);
+      return ADBC_STATUS_IO;
+    }
+
+    if (!binder->array.release) {
+      *finished = 1;
+      AdbcSqliteBinderRelease(binder);
+      return ADBC_STATUS_OK;
+    }
+
+    rc = ArrowArrayViewSetArray(&binder->batch, &binder->array, &arrow_error);
+    if (rc != 0) {
+      SetError(error, "Failed to initialize array view: (%d) %s: %s", rc, 
strerror(rc),
+               arrow_error.message);
+      return ADBC_STATUS_INTERNAL;
+    }
+
+    binder->next_row = 0;
+  }
+
+  if (sqlite3_reset(stmt) != SQLITE_OK) {
+    SetError(error, "Failed to reset statement: %s", sqlite3_errmsg(conn));
+    return ADBC_STATUS_INTERNAL;
+  }
+  if (sqlite3_clear_bindings(stmt) != SQLITE_OK) {
+    SetError(error, "Failed to clear statement bindings: %s", 
sqlite3_errmsg(conn));
+    return ADBC_STATUS_INTERNAL;
+  }
+
+  for (int col = 0; col < binder->schema.n_children; col++) {
+    if (ArrowArrayViewIsNull(binder->batch.children[col], binder->next_row)) {
+      rc = sqlite3_bind_null(stmt, col + 1);
+    } else {
+      switch (binder->types[col]) {
+        case NANOARROW_TYPE_BINARY:
+        case NANOARROW_TYPE_LARGE_BINARY: {
+          struct ArrowBufferView value =
+              ArrowArrayViewGetBytesUnsafe(binder->batch.children[col], 
binder->next_row);
+          rc = sqlite3_bind_text(stmt, col + 1, value.data.as_char, 
value.n_bytes,
+                                 SQLITE_STATIC);
+          break;
+        }
+        case NANOARROW_TYPE_INT64: {
+          int64_t value =
+              ArrowArrayViewGetIntUnsafe(binder->batch.children[col], 
binder->next_row);
+          rc = sqlite3_bind_int64(stmt, col + 1, value);
+          break;
+        }
+        case NANOARROW_TYPE_STRING:

Review Comment:
   Type coverage is pretty bad right now. I'll add some more test cases.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscr...@arrow.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to