pgRouting
pgRouting extends the PostGIS / PostgreSQL geospatial database to provide geospatial routing functionality.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
arrays_input.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: arrays_input.c
3 
4 Copyright (c) 2015 Celia Virginia Vergara Castillo
5 vicky_vergara@hotmail.com
6 
7 ------
8 
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 
23 ********************************************************************PGR-GNU*/
24 
25 #include <postgres.h>
26 #include "utils/lsyscache.h"
27 #include "catalog/pg_type.h"
28 #include "utils/array.h"
29 
30 
31 // #define DEBUG
32 #include "./pgr_types.h"
33 #include "./time_msg.h"
34 #include "./debug_macro.h"
35 #include "./arrays_input.h"
36 
37 
38 int64_t* pgr_get_bigIntArray(size_t *arrlen, ArrayType *input) {
39  int ndims;
40  bool *nulls;
41  Oid i_eltype;
42  int16 i_typlen;
43  bool i_typbyval;
44  char i_typalign;
45  Datum *i_data;
46  int i;
47  int n;
48  int64_t *data;
49  clock_t start_t = clock();
50 
51  PGR_DBG("Getting integer array");
52  /* get input array element type */
53  i_eltype = ARR_ELEMTYPE(input);
54  get_typlenbyvalalign(i_eltype, &i_typlen, &i_typbyval, &i_typalign);
55 
56  /* validate input data type */
57  switch (i_eltype) {
58  case INT2OID:
59  case INT4OID:
60  case INT8OID:
61  break;
62  default:
63  elog(ERROR, "Expected array of ANY-INTEGER");
64  return (int64_t*) NULL;
65  break;
66  }
67 
68  /* get various pieces of data from the input array */
69  ndims = ARR_NDIM(input);
70  n = (*ARR_DIMS(input));
71  (*arrlen) = (size_t)(n);
72 
73  if (ndims != 1) {
74  elog(ERROR, "One dimension expected");
75  }
76 
77  /* get src data */
78  deconstruct_array(input, i_eltype, i_typlen, i_typbyval, i_typalign,
79  &i_data, &nulls, &n);
80 
81  /* construct a C array */
82  data = (int64_t *) malloc((*arrlen) * sizeof(int64_t));
83 
84  if (!data) {
85  elog(ERROR, "Out of memory!");
86  }
87 
88  PGR_DBG("array size %ld", (*arrlen));
89 
90  for (i = 0; i < (*arrlen); i++) {
91  if (nulls[i]) {
92  free(data);
93  elog(ERROR, "NULL value found in Array!");
94  } else {
95  switch (i_eltype) {
96  case INT2OID:
97  data[i] = (int64_t) DatumGetInt16(i_data[i]);
98  break;
99  case INT4OID:
100  data[i] = (int64_t) DatumGetInt32(i_data[i]);
101  break;
102  case INT8OID:
103  data[i] = DatumGetInt64(i_data[i]);
104  break;
105  }
106  }
107  }
108 
109  pfree(nulls);
110  pfree(i_data);
111 
112  PGR_DBG("Finished processing array");
113  time_msg(" reading Array", start_t, clock());
114  return (int64_t*)data;
115 }
116 
117 
118 
119 int64_t* pgr_get_bigIntArray_allowEmpty(size_t *arrlen, ArrayType *input) {
120  int ndims;
121  bool *nulls;
122  Oid i_eltype;
123  int16 i_typlen;
124  bool i_typbyval;
125  char i_typalign;
126  Datum *i_data;
127  int i;
128  int n;
129  int64_t *data;
130  clock_t start_t = clock();
131 
132  PGR_DBG("Getting integer array");
133  /* get input array element type */
134  i_eltype = ARR_ELEMTYPE(input);
135  get_typlenbyvalalign(i_eltype, &i_typlen, &i_typbyval, &i_typalign);
136 
137  /* validate input data type */
138  switch (i_eltype) {
139  case INT2OID:
140  case INT4OID:
141  case INT8OID:
142  break;
143  default:
144  elog(ERROR, "Expected array of ANY-INTEGER");
145  return (int64_t*) NULL;
146  break;
147  }
148 
149  /* get various pieces of data from the input array */
150  ndims = ARR_NDIM(input);
151  n = (*ARR_DIMS(input));
152  (*arrlen) = (size_t)(n);
153  // PGR_DBG("dimensions %d", ndims);
154  // PGR_DBG("array size %ld", (*arrlen));
155 
156  if (ndims == 0) {
157  (*arrlen) = 0;
158  PGR_DBG("array size %ld", (*arrlen));
159  return (int64_t*) NULL;
160  }
161 
162  if (ndims > 1) {
163  elog(ERROR, "Expected less than two dimension");
164  }
165 
166  /* get src data */
167  deconstruct_array(input, i_eltype, i_typlen, i_typbyval, i_typalign,
168  &i_data, &nulls, &n);
169 
170  /* construct a C array */
171  data = (int64_t *) malloc((*arrlen) * sizeof(int64_t));
172 
173  if (!data) {
174  elog(ERROR, "Out of memory!");
175  }
176 
177  PGR_DBG("array size %ld", (*arrlen));
178 
179  for (i = 0; i < (*arrlen); i++) {
180  if (nulls[i]) {
181  free(data);
182  elog(ERROR, "NULL value found in Array!");
183  } else {
184  switch (i_eltype) {
185  case INT2OID:
186  data[i] = (int64_t) DatumGetInt16(i_data[i]);
187  break;
188  case INT4OID:
189  data[i] = (int64_t) DatumGetInt32(i_data[i]);
190  break;
191  case INT8OID:
192  data[i] = DatumGetInt64(i_data[i]);
193  break;
194  }
195  }
196  }
197 
198  pfree(nulls);
199  pfree(i_data);
200 
201  PGR_DBG("Finished processing array");
202  time_msg(" reading Array", start_t, clock());
203  return (int64_t*)data;
204 }
#define PGR_DBG(...)
Definition: debug_macro.h:33
int64_t * pgr_get_bigIntArray_allowEmpty(size_t *arrlen, ArrayType *input)
Definition: arrays_input.c:119
int64_t * pgr_get_bigIntArray(size_t *arrlen, ArrayType *input)
Definition: arrays_input.c:38
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:31