PGROUTING  3.2
get_check_data.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: get_check_data.c
3 
4 Copyright (c) 2015 Celia Virginia Vergara Castillo
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 <stdbool.h>
28 #include "c_common/arrays_input.h"
29 
30 #include "catalog/pg_type.h"
31 
32 #include "c_common/debug_macro.h"
33 
34 
35 bool
36 column_found(int colNumber) {
37  /*
38  * [SPI_ERROR_NOATTRIBUTE](https://doxygen.postgresql.org/spi_8h.html#ac1512d8aaa23c2d57bb0d1eb8f453ee2)
39  */
40  return !(colNumber == SPI_ERROR_NOATTRIBUTE);
41 }
42 
43 static
44 bool
46  Column_info_t *info) {
47 /* TODO(vicky) Remove unused code */
48 #if 0
49  PGR_DBG("Fetching column info of %s", info->name);
50 #endif
51  /*
52  * [SPI_fnumber](https://www.postgresql.org/docs/8.2/static/spi-spi-fnumber.html)
53  */
54  info->colNumber = SPI_fnumber(SPI_tuptable->tupdesc, info->name);
55  if (info->strict && !column_found(info->colNumber)) {
56  elog(ERROR, "Column '%s' not Found", info->name);
57  }
58 
59  if (column_found(info->colNumber)) {
60  /*
61  * [SPI_gettypeid](https://www.postgresql.org/docs/9.1/static/spi-spi-gettypeid.html)
62  */
63  (info->type) = SPI_gettypeid(SPI_tuptable->tupdesc, (info->colNumber));
64  if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
65  elog(ERROR, "Type of column '%s' not Found", info->name);
66  }
67 /* TODO(vicky) Remove unused code */
68 #if 0
69  PGR_DBG("Column %s found: %lu", info->name, info->type);
70 #endif
71  return true;
72  }
73  PGR_DBG("Column %s not found", info->name);
74  return false;
75 }
76 
77 
79  Column_info_t info[],
80  int info_size) {
81  int i;
82  for (i = 0; i < info_size; ++i) {
83  if (fetch_column_info(&info[i])) {
84  switch (info[i].eType) {
85  case ANY_INTEGER:
87  break;
88  case ANY_NUMERICAL:
90  break;
91  case TEXT:
92  pgr_check_text_type(info[i]);
93  break;
94  case CHAR1:
95  pgr_check_char_type(info[i]);
96  break;
97  case ANY_INTEGER_ARRAY:
99  break;
100  default:
101  elog(ERROR, "Unknown type of column %s", info[i].name);
102  }
103  }
104  }
105 }
106 
107 /*
108  * [BPCHAROID](https://doxygen.postgresql.org/include_2catalog_2pg__type_8h.html#afa7749dbe36d31874205189d9d6b21d7)
109  * [INT2ARRAYOID](https://doxygen.postgresql.org/include_2catalog_2pg__type_8h.html#ac265fe7b0bb75fead13b16bf072722e9)
110  */
111 
112 void
114  if (!(info.type == BPCHAROID)) {
115  elog(ERROR, "Unexpected Column '%s' type. Expected CHAR", info.name);
116  }
117 }
118 
119 void
121  if (!(info.type == TEXTOID)) {
122  elog(ERROR, "Unexpected Column '%s' type. Expected TEXT", info.name);
123  }
124 }
125 
126 void
128  if (!(info.type == INT2OID
129  || info.type == INT4OID
130  || info.type == INT8OID)) {
131  elog(ERROR,
132  "Unexpected Column '%s' type. Expected ANY-INTEGER",
133  info.name);
134  }
135 }
136 
137 void
139  if (!(info.type == INT2ARRAYOID
140  || info.type == INT4ARRAYOID
141  || info.type == 1016)) {
142  elog(ERROR,
143  "Unexpected Column '%s' type. Expected ANY-INTEGER-ARRAY",
144  info.name);
145  }
146 }
147 
149  if (!(info.type == INT2OID
150  || info.type == INT4OID
151  || info.type == INT8OID
152  || info.type == FLOAT4OID
153  || info.type == FLOAT8OID
154  || info.type == NUMERICOID)) {
155  elog(ERROR,
156  "Unexpected Column '%s' type. Expected ANY-NUMERICAL",
157  info.name);
158  }
159 }
160 
161 
162 /*
163  * http://doxygen.postgresql.org/include_2catalog_2pg__type_8h.html;
164  * [SPI_getbinval](https://www.postgresql.org/docs/8.1/static/spi-spi-getbinval.html)
165  * [Datum](https://doxygen.postgresql.org/datum_8h.html)
166  * [DatumGetInt16](https://doxygen.postgresql.org/postgres_8h.html#aec991e04209850f29a8a63df0c78ba2d)
167  */
168 
169 char
171  HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info,
172  bool strict, char default_value) {
173  Datum binval;
174  bool isNull;
175  char value = default_value;
176 
177  binval = SPI_getbinval(*tuple, *tupdesc, info.colNumber, &isNull);
178  if (!(info.type == BPCHAROID)) {
179  elog(ERROR, "Unexpected Column type of %s. Expected CHAR", info.name);
180  }
181  if (!isNull) {
182  value = ((char*)binval)[1];
183  } else {
184  if (strict) {
185  elog(ERROR, "Unexpected Null value in column %s", info.name);
186  }
187  value = default_value;
188  }
189  return value;
190 }
191 
192 
193 
194 
195 int64_t*
197  HeapTuple *tuple,
198  TupleDesc *tupdesc,
199  Column_info_t info,
200  uint64_t *the_size) {
201  bool is_null = false;
202 
203  Datum raw_array = SPI_getbinval(*tuple, *tupdesc, info.colNumber, &is_null);
204  /*
205  * [DatumGetArrayTypeP](https://doxygen.postgresql.org/array_8h.html#aa1b8e77c103863862e06a7b7c07ec532)
206  * [pgr_get_bigIntArray](http://docs.pgrouting.org/doxy/2.2/arrays__input_8c_source.html)
207  */
208  ArrayType *pg_array = DatumGetArrayTypeP(raw_array);
209 
210  return pgr_get_bigIntArray((size_t*)the_size, pg_array);
211 }
212 
213 
214 
215 int64_t
216 pgr_SPI_getBigInt(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info) {
217  Datum binval;
218  bool isnull;
219  int64_t value = 0;
220  binval = SPI_getbinval(*tuple, *tupdesc, info.colNumber, &isnull);
221  if (isnull)
222  elog(ERROR, "Unexpected Null value in column %s", info.name);
223  switch (info.type) {
224  case INT2OID:
225  value = (int64_t) DatumGetInt16(binval);
226  break;
227  case INT4OID:
228  value = (int64_t) DatumGetInt32(binval);
229  break;
230  case INT8OID:
231  value = DatumGetInt64(binval);
232  break;
233  default:
234  elog(ERROR,
235  "Unexpected Column type of %s. Expected ANY-INTEGER",
236  info.name);
237  }
238 /* TODO(vicky) Remove unused code */
239 #if 0
240  PGR_DBG("Variable: %s Value: %ld", info.name, value);
241 #endif
242  return value;
243 }
244 
245 double
246 pgr_SPI_getFloat8(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info) {
247  Datum binval;
248  bool isnull = false;
249  double value = 0.0;
250  binval = SPI_getbinval(*tuple, *tupdesc, info.colNumber, &isnull);
251  if (isnull)
252  elog(ERROR, "Unexpected Null value in column %s", info.name);
253 
254  switch (info.type) {
255  case INT2OID:
256  value = (double) DatumGetInt16(binval);
257  break;
258  case INT4OID:
259  value = (double) DatumGetInt32(binval);
260  break;
261  case INT8OID:
262  value = (double) DatumGetInt64(binval);
263  break;
264  case FLOAT4OID:
265  value = (double) DatumGetFloat4(binval);
266  break;
267  case FLOAT8OID:
268  value = DatumGetFloat8(binval);
269  break;
270  case NUMERICOID:
271  /* Note: out-of-range values will be clamped to +-HUGE_VAL */
272  value = (double) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, binval));
273  break;
274  default:
275  elog(ERROR,
276  "Unexpected Column type of %s. Expected ANY-NUMERICAL",
277  info.name);
278  }
279 /* TODO(vicky) Remove unused code */
280 #if 0
281  PGR_DBG("Variable: %s Value: %.20f", info.name, value);
282 #endif
283  return value;
284 }
285 
289 /*
290  * [DatumGetCString](https://doxygen.postgresql.org/postgres_8h.html#ae401c8476d1a12b420e3061823a206a7)
291  */
292 char*
293 pgr_SPI_getText(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info) {
294  return DatumGetCString(SPI_getvalue(*tuple, *tupdesc, info.colNumber));
295 }
Column_info_t::colNumber
int colNumber
Definition: column_info_t.h:51
fetch_column_info
static bool fetch_column_info(Column_info_t *info)
Definition: get_check_data.c:45
postgres_connection.h
pgr_SPI_getBigIntArr
int64_t * pgr_SPI_getBigIntArr(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, uint64_t *the_size)
Function returns the values of specified columns in array.
Definition: get_check_data.c:196
pgr_check_any_integer_type
void pgr_check_any_integer_type(Column_info_t info)
The function check whether column type is ANY-INTEGER or not.
Definition: get_check_data.c:127
Column_info_t::strict
bool strict
Definition: column_info_t.h:53
pgr_SPI_getText
char * pgr_SPI_getText(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
under development
Definition: get_check_data.c:293
TEXT
@ TEXT
Definition: column_info_t.h:43
pgr_check_char_type
void pgr_check_char_type(Column_info_t info)
The function check whether column type is CHAR or not.
Definition: get_check_data.c:113
arrays_input.h
pgr_SPI_getBigInt
int64_t pgr_SPI_getBigInt(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
Function returns the value of specified column in integer type.
Definition: get_check_data.c:216
pgr_fetch_column_info
void pgr_fetch_column_info(Column_info_t info[], int info_size)
Function tells expected type of each column and then check the correspondence type of each column.
Definition: get_check_data.c:78
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:146
pgr_SPI_getChar
char pgr_SPI_getChar(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info, bool strict, char default_value)
Function return the value of specified column in char type.
Definition: get_check_data.c:170
pgr_check_text_type
void pgr_check_text_type(Column_info_t info)
The function check whether column type is TEXT or not.
Definition: get_check_data.c:120
Column_info_t::name
char * name
Definition: column_info_t.h:54
PGR_DBG
#define PGR_DBG(...)
Definition: debug_macro.h:34
pgr_check_any_integerarray_type
void pgr_check_any_integerarray_type(Column_info_t info)
The function check whether column type is ANY-INTEGER-ARRAY or not.
Definition: get_check_data.c:138
ANY_INTEGER_ARRAY
@ ANY_INTEGER_ARRAY
Definition: column_info_t.h:45
pgr_SPI_getFloat8
double pgr_SPI_getFloat8(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
Function returns the value of specified column in double type.
Definition: get_check_data.c:246
pgr_check_any_numerical_type
void pgr_check_any_numerical_type(Column_info_t info)
The function check whether column type is ANY-NUMERICAL.
Definition: get_check_data.c:148
ANY_INTEGER
@ ANY_INTEGER
Definition: column_info_t.h:41
ANY_NUMERICAL
@ ANY_NUMERICAL
Definition: column_info_t.h:42
column_found
bool column_found(int colNumber)
Function will check whether the colNumber represent any specific column or NULL (SPI_ERROR_NOATTRIBUT...
Definition: get_check_data.c:36
get_check_data.h
Column_info_t::type
uint64_t type
Definition: column_info_t.h:52
CHAR1
@ CHAR1
Definition: column_info_t.h:44
Column_info_t
Definition: column_info_t.h:49