code: def executemanycolumns(self, sql, columns):
          
          self.rowcount = -1
          self._assert_valid()
  
          self.impl.prepare(sql)
  
          if _has_arrow_support():
              import pyarrow as pa
              if isinstance(columns, pa.Table):
                  from turbodbc_arrow_support import set_arrow_parameters
  
                  for column in columns.itercolumns():
                      if column.data.num_chunks != 1:
                          raise NotImplementedError("Chunked Arrays are not yet supported")
  
                  set_arrow_parameters(self.impl, columns)
                  return self._execute()
  
          # Workaround to give users a better error message without a need
          # to import pyarrow
          if columns.__class__.__module__.startswith('pyarrow'):
              raise Error(_NO_ARROW_SUPPORT_MSG)
  
          if not _has_numpy_support():
              raise Error(_NO_NUMPY_SUPPORT_MSG)
  
          _assert_numpy_column_preconditions(columns)
  
  
          from numpy.ma import MaskedArray
          from turbodbc_numpy_support import set_numpy_parameters
          split_arrays = []
          for column in columns:
              if isinstance(column, MaskedArray):
                  split_arrays.append((column.data, column.mask, str(column.dtype)))
              else:
                  split_arrays.append((column, False, str(column.dtype)))
          set_numpy_parameters(self.impl, split_arrays)
  
          return self._execute()
docs: Execute an SQL command or query with multiple parameter sets that are passed in
          a column-wise fashion as opposed to the row-wise parameters in ``executemany()``.
          This function is a turbodbc-specific extension to PEP-249.
  
          :param sql: A (unicode) string that contains the SQL command or query. If you would like to
                 use parameters, please use a question mark ``?`` at the location where the
                 parameter shall be inserted.
          :param columns: An iterable of NumPy MaskedArrays. The Arrays represent the columnar
                 parameter data,
          :return: The ``Cursor`` object to allow chaining of operations.