10
votes

PostgreSQL libpq: codage pour le transport binaire de tableau [] - données?

Après des heures de documentation / planches / de mailinglists et aucun progrès, je peux vous demander: comment puis-je "encoder" mes données à l'utiliser pour le transport binaire à l'aide de PQEXecParams de libpq (.) ?

Les variables simples sont juste dans la grosse commande Endian: xxx

et comme cela aussi double, int, etc ...

mais que diriez-vous des tableaux? xxx

existe-t-il un exemple de travail de transfert de données de réseau dans le format binaire de PostgreSQL? Le code dans backend / utils / adt / ne m'aide pas beaucoup (sauf que je sais maintenant qu'il y a un arrayype, mais pas comment les utiliser): - (

i il suffit de besoin d'une fonction char * to_pqbin (entrée de flotteur [], int longueur) pour passer à paramvalues ​​[.] ...

Merci beaucoup , TEBAS

PS: Quelle est la manière suggérée de convertir des variables simples (plutôt que mon htobe32 (.) )?


0 commentaires

3 Réponses :


11
votes

3 commentaires

Cette réponse fait un excellent travail de résumant la structure de la matrice et était très utile! Je suis un peu perplexe par ces deux déclarations: "[...] un tableau de 4 entiers [...]" et "[...] matrices brutes, chaque élément préfixé par sa longueur (4 octets pour chaque entiers ). " Dans la décharge hexagonale, il y a 4 entiers valorisés 4. Quelque chose est étrange ici. Il devrait être soit une taille de matrice de 2, soit il devrait y avoir 8 entiers dans la décharge hexagonale, ou je reçois quelque chose d'horriblement faux.


@antiPattern, avez-vous eu pour le savoir? Crocuter, pourriez-vous éclaircir l'incohérence?


Dans l'arrière-plan, je suppose que cette déclaration est la clé: "omettez la partie vl_len_" - Ainsi, pas de longueur supplémentaire, mais seulement 4 entiers valorisés 4. Je suggère que l'utilisation de la valeur numérique 4 pour les valeurs de données ici est trompeuse; Comme tout autre numéro pouvait être choisi, ce qui faciliterait la distinction.



5
votes

comme Collage Strong> déjà mentionné, vous devez créer votre propre API. Le code suivant extrait un tableau 1 dimension de int 4 code> s imorcent toutes les valeurs null.

#define   INT4OID   23

/*! Structure of array header to determine array type */
struct array_int4 {
  int32_t ndim; /* Number of dimensions */
  int32_t _ign; /* offset for data, removed by libpq */
  Oid elemtype; /* type of element in the array */

  /* First dimension */
  int32_t size; /* Number of elements */
  int32_t index; /* Index of first element */
  int32_t first_value; /* Beginning of integer data */
};

static int extract_int4_array (char *raw_array, 
                               int32_t **values, 
                               int *num_values) {
  /* Array information header */
  struct array_int4 *array = (struct array_int4 *) raw_array; 
  /* Pointer to traverse int array */
  int32_t *p_value = &(array->first_value);
  /* int value in host byte order */
  int32_t hval;

  /* Check if we have a 1-dimensional INT4 array */
  if (ntohl(array->ndim) != 1 
  || ntohl(array->elemtype) != INT4OID) {
    return -1;
  }
  /* Number of elements including NULLs */
  int array_elements = ntohl (array->size);

  *num_values = 0;
  /* Get size of array */
  for (int i=0; i<array_elements; ++i) {
    /* Check size to see if this is a NULL value */
    hval = ntohl (*p_value);
    if (hval != -1) {
      ++p_value;
      (*num_values) += 1;
    } 

    ++p_value;
  }
  *values = malloc (*num_values * sizeof **values);

  /* Fill output int array. Skip every other value as it contains the size of 
   * the element */
  *num_values = 0; /* Use num_values as the index of the output array */
  p_value = &(array->first_value);
  for (int i=0; i<array_elements; ++i) {
    /* Check size to see if this is a NULL value */
    hval = ntohl (*p_value);
    if (hval != -1) {
      ++p_value;
  (*values)[*num_values] = ntohl (*p_value);
      (*num_values) += 1;
    } 

    ++p_value;
  }

  return 0;
}


0 commentaires

0
votes

Voici ce que j'ai réussi à faire du travail dans Node.js / Typescript:

function writeInt4Array(buffer: Buffer, values: number[], offset: number): number {
  offset = buffer.writeInt32BE(1, offset) // Number of dimensions
  offset = buffer.writeInt32BE(0, offset) // Has nulls?
  offset = buffer.writeInt32BE(ObjectId.Int4, offset) // Element type
  offset = buffer.writeInt32BE(values.length, offset) // Size of first dimension
  offset = buffer.writeInt32BE(1, offset) // Offset (starting index) of first dimension
  for (const v of values) {
    offset = buffer.writeInt32BE(4, offset)
    offset = buffer.writeInt32BE(v, offset)
  }
  return offset
}


0 commentaires