00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "postgres.h"
00017
00018 #include "catalog/pg_type.h"
00019 #include "utils/array.h"
00020 #include "utils/builtins.h"
00021 #include "utils/memutils.h"
00022
00023
00024
00025
00026
00027
00028
00029
00030 int
00031 ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx)
00032 {
00033 int i,
00034 scale = 1,
00035 offset = 0;
00036
00037 for (i = n - 1; i >= 0; i--)
00038 {
00039 offset += (indx[i] - lb[i]) * scale;
00040 scale *= dim[i];
00041 }
00042 return offset;
00043 }
00044
00045
00046
00047
00048
00049 int
00050 ArrayGetOffset0(int n, const int *tup, const int *scale)
00051 {
00052 int i,
00053 lin = 0;
00054
00055 for (i = 0; i < n; i++)
00056 lin += tup[i] * scale[i];
00057 return lin;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 int
00075 ArrayGetNItems(int ndim, const int *dims)
00076 {
00077 int32 ret;
00078 int i;
00079
00080 #define MaxArraySize ((Size) (MaxAllocSize / sizeof(Datum)))
00081
00082 if (ndim <= 0)
00083 return 0;
00084 ret = 1;
00085 for (i = 0; i < ndim; i++)
00086 {
00087 int64 prod;
00088
00089
00090 if (dims[i] < 0)
00091 ereport(ERROR,
00092 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
00093 errmsg("array size exceeds the maximum allowed (%d)",
00094 (int) MaxArraySize)));
00095
00096 prod = (int64) ret *(int64) dims[i];
00097
00098 ret = (int32) prod;
00099 if ((int64) ret != prod)
00100 ereport(ERROR,
00101 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
00102 errmsg("array size exceeds the maximum allowed (%d)",
00103 (int) MaxArraySize)));
00104 }
00105 Assert(ret >= 0);
00106 if ((Size) ret > MaxArraySize)
00107 ereport(ERROR,
00108 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
00109 errmsg("array size exceeds the maximum allowed (%d)",
00110 (int) MaxArraySize)));
00111 return (int) ret;
00112 }
00113
00114
00115
00116
00117
00118
00119 void
00120 mda_get_range(int n, int *span, const int *st, const int *endp)
00121 {
00122 int i;
00123
00124 for (i = 0; i < n; i++)
00125 span[i] = endp[i] - st[i] + 1;
00126 }
00127
00128
00129
00130
00131
00132
00133 void
00134 mda_get_prod(int n, const int *range, int *prod)
00135 {
00136 int i;
00137
00138 prod[n - 1] = 1;
00139 for (i = n - 2; i >= 0; i--)
00140 prod[i] = prod[i + 1] * range[i + 1];
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 void
00150 mda_get_offset_values(int n, int *dist, const int *prod, const int *span)
00151 {
00152 int i,
00153 j;
00154
00155 dist[n - 1] = 0;
00156 for (j = n - 2; j >= 0; j--)
00157 {
00158 dist[j] = prod[j] - 1;
00159 for (i = j + 1; i < n; i++)
00160 dist[j] -= (span[i] - 1) * prod[i];
00161 }
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 int
00175 mda_next_tuple(int n, int *curr, const int *span)
00176 {
00177 int i;
00178
00179 if (n <= 0)
00180 return -1;
00181
00182 curr[n - 1] = (curr[n - 1] + 1) % span[n - 1];
00183 for (i = n - 1; i && curr[i] == 0; i--)
00184 curr[i - 1] = (curr[i - 1] + 1) % span[i - 1];
00185
00186 if (i)
00187 return i;
00188 if (curr[0])
00189 return 0;
00190
00191 return -1;
00192 }
00193
00194
00195
00196
00197
00198
00199 int32 *
00200 ArrayGetIntegerTypmods(ArrayType *arr, int *n)
00201 {
00202 int32 *result;
00203 Datum *elem_values;
00204 int i;
00205
00206 if (ARR_ELEMTYPE(arr) != CSTRINGOID)
00207 ereport(ERROR,
00208 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
00209 errmsg("typmod array must be type cstring[]")));
00210
00211 if (ARR_NDIM(arr) != 1)
00212 ereport(ERROR,
00213 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
00214 errmsg("typmod array must be one-dimensional")));
00215
00216 if (array_contains_nulls(arr))
00217 ereport(ERROR,
00218 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
00219 errmsg("typmod array must not contain nulls")));
00220
00221
00222 deconstruct_array(arr, CSTRINGOID,
00223 -2, false, 'c',
00224 &elem_values, NULL, n);
00225
00226 result = (int32 *) palloc(*n * sizeof(int32));
00227
00228 for (i = 0; i < *n; i++)
00229 result[i] = pg_atoi(DatumGetCString(elem_values[i]),
00230 sizeof(int32), '\0');
00231
00232 pfree(elem_values);
00233
00234 return result;
00235 }