vrpRouting  0.3
arrays_input.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: arrays_input.c
3 
4 Copyright (c) 2015 pgRouting developers
6 
7 Developer:
8 Copyright (c) 2015 Celia Virginia Vergara Castillo
9 
10 ------
11 
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16 
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21 
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 
26  ********************************************************************PGR-GNU*/
27 /* @file */
28 
29 #include "c_common/arrays_input.h"
30 
31 #include <assert.h>
32 #include <utils/lsyscache.h>
33 #include <catalog/pg_type.h>
34 
35 
36 #ifdef PROFILE
37 #include "c_common/debug_macro.h"
38 #endif
39 
40 static
41 int64_t*
42 pgr_get_bigIntArr(ArrayType *v, size_t *arrlen, bool allow_empty) {
43 #ifdef PROFILE
44  clock_t start_t = clock();
45 #endif
46 
47  int64_t *c_array = NULL;
48 
49  Oid element_type = ARR_ELEMTYPE(v);
50  int *dim = ARR_DIMS(v);
51  int ndim = ARR_NDIM(v);
52  int nitems = ArrayGetNItems(ndim, dim);
53  Datum *elements;
54  bool *nulls;
55  int16 typlen;
56  bool typbyval;
57  char typalign;
58 
59  assert((*arrlen) == 0);
60 
61 
62  if (allow_empty && (ndim == 0 || nitems <= 0)) {
63  return (int64_t*) NULL;
64  }
65  /* the array is not empty*/
66 
67  if (ndim != 1) {
68  elog(ERROR, "One dimension expected");
69  }
70 
71  if (nitems <= 0) {
72  elog(ERROR, "No elements found");
73  }
74 
75  get_typlenbyvalalign(element_type,
76  &typlen, &typbyval, &typalign);
77 
78  /* validate input data type */
79  switch (element_type) {
80  case INT2OID:
81  case INT4OID:
82  case INT8OID:
83  break;
84  default:
85  elog(ERROR, "Expected array of ANY-INTEGER");
86  }
87 
88  deconstruct_array(v, element_type, typlen, typbyval,
89  typalign, &elements, &nulls,
90  &nitems);
91 
92  c_array = (int64_t *) palloc(sizeof(int64_t) * (size_t)nitems);
93  if (!c_array) {
94  elog(ERROR, "Out of memory!");
95  }
96 
97 
98  int i;
99  for (i = 0; i < nitems; i++) {
100  if (nulls[i]) {
101  pfree(c_array);
102  elog(ERROR, "NULL value found in Array!");
103  } else {
104  switch (element_type) {
105  case INT2OID:
106  c_array[i] = (int64_t) DatumGetInt16(elements[i]);
107  break;
108  case INT4OID:
109  c_array[i] = (int64_t) DatumGetInt32(elements[i]);
110  break;
111  case INT8OID:
112  c_array[i] = DatumGetInt64(elements[i]);
113  break;
114  }
115  }
116  }
117  (*arrlen) = (size_t)nitems;
118 
119  pfree(elements);
120  pfree(nulls);
121 #ifdef PROFILE
122  time_msg("reading Array", start_t, clock());
123 #endif
124  return c_array;
125 }
126 
127 
128 static
129 uint32_t*
130 pgr_get_positiveIntArr(ArrayType *v, size_t *arrlen, bool allow_empty) {
131 #ifdef PROFILE
132  clock_t start_t = clock();
133 #endif
134 
135  uint32_t *c_array = NULL;
136 
137  Oid element_type = ARR_ELEMTYPE(v);
138  int *dim = ARR_DIMS(v);
139  int ndim = ARR_NDIM(v);
140  int nitems = ArrayGetNItems(ndim, dim);
141  Datum *elements;
142  bool *nulls;
143  int16 typlen;
144  bool typbyval;
145  char typalign;
146 
147  assert((*arrlen) == 0);
148 
149 
150  if (allow_empty && (ndim == 0 || nitems <= 0)) {
151  return (uint32_t*) NULL;
152  }
153  /* the array is not empty*/
154 
155  if (ndim != 1) {
156  elog(ERROR, "One dimension expected");
157  }
158 
159  if (nitems <= 0) {
160  elog(ERROR, "No elements found");
161  }
162 
163  get_typlenbyvalalign(element_type,
164  &typlen, &typbyval, &typalign);
165 
166  /* validate input data type */
167  switch (element_type) {
168  case INT2OID:
169  case INT4OID:
170  break;
171  default:
172  elog(ERROR, "Expected array of INTEGER");
173  }
174 
175  deconstruct_array(v, element_type, typlen, typbyval,
176  typalign, &elements, &nulls,
177  &nitems);
178 
179  c_array = (uint32_t *) palloc(sizeof(uint32_t) * (size_t)nitems);
180  if (!c_array) {
181  elog(ERROR, "Out of memory!");
182  }
183 
184 
185  int i;
186  for (i = 0; i < nitems; i++) {
187  if (nulls[i]) {
188  pfree(c_array);
189  elog(ERROR, "NULL value found in Array!");
190  } else {
191  int32_t element;
192  switch (element_type) {
193  case INT2OID:
194  element = (int32_t) DatumGetInt16(elements[i]);
195  break;
196  case INT4OID:
197  element = (int32_t) DatumGetInt32(elements[i]);
198  break;
199  }
200  if (element < 0) {
201  elog(ERROR, "Unexpected Negative value %d in array", element);
202  }
203  c_array[i] = (uint32_t) element;
204  }
205  }
206  (*arrlen) = (size_t)nitems;
207 
208  pfree(elements);
209  pfree(nulls);
210 #ifdef PROFILE
211  time_msg("reading Array", start_t, clock());
212 #endif
213  return c_array;
214 }
215 
216 
217 int64_t* pgr_get_bigIntArray(size_t *arrlen, ArrayType *input) {
218  return pgr_get_bigIntArr(input, arrlen, false);
219 }
220 
221 
222 
223 int64_t* pgr_get_bigIntArray_allowEmpty(size_t *arrlen, ArrayType *input) {
224  return pgr_get_bigIntArr(input, arrlen, true);
225 }
226 
227 
228 uint32_t* pgr_get_positiveIntArray_allowEmpty(size_t *arrlen, ArrayType *input) {
229  return pgr_get_positiveIntArr(input, arrlen, true);
230 }
pgr_get_bigIntArr
static int64_t * pgr_get_bigIntArr(ArrayType *v, size_t *arrlen, bool allow_empty)
Definition: arrays_input.c:42
arrays_input.h
debug_macro.h
pgr_get_bigIntArray
int64_t * pgr_get_bigIntArray(size_t *arrlen, ArrayType *input)
enforces the input array to be NOT empty
Definition: arrays_input.c:217
pgr_get_bigIntArray_allowEmpty
int64_t * pgr_get_bigIntArray_allowEmpty(size_t *arrlen, ArrayType *input)
Allows the input array to be empty.
Definition: arrays_input.c:223
pgr_get_positiveIntArray_allowEmpty
uint32_t * pgr_get_positiveIntArray_allowEmpty(size_t *arrlen, ArrayType *input)
Allows the input array, with non-negative elements to be empty.
Definition: arrays_input.c:228
time_msg
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:32
pgr_get_positiveIntArr
static uint32_t * pgr_get_positiveIntArr(ArrayType *v, size_t *arrlen, bool allow_empty)
Definition: arrays_input.c:130