]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/varlena.c
Create a new GUC variable search_path to control the namespace search
[postgresql] / src / backend / utils / adt / varlena.c
1 /*-------------------------------------------------------------------------
2  *
3  * varlena.c
4  *        Functions for the variable-length built-in types.
5  *
6  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.81 2002/04/01 03:34:26 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17 #include <ctype.h>
18
19 #include "mb/pg_wchar.h"
20 #include "miscadmin.h"
21 #include "utils/builtins.h"
22
23 static int      text_cmp(text *arg1, text *arg2);
24
25
26 /*****************************************************************************
27  *       USER I/O ROUTINES                                                                                                               *
28  *****************************************************************************/
29
30
31 #define VAL(CH)                 ((CH) - '0')
32 #define DIG(VAL)                ((VAL) + '0')
33
34 /*
35  *              byteain                 - converts from printable representation of byte array
36  *
37  *              Non-printable characters must be passed as '\nnn' (octal) and are
38  *              converted to internal form.  '\' must be passed as '\\'.
39  *              elog(ERROR, ...) if bad form.
40  *
41  *              BUGS:
42  *                              The input is scaned twice.
43  *                              The error checking of input is minimal.
44  */
45 Datum
46 byteain(PG_FUNCTION_ARGS)
47 {
48         char       *inputText = PG_GETARG_CSTRING(0);
49         char       *tp;
50         char       *rp;
51         int                     byte;
52         bytea      *result;
53
54         for (byte = 0, tp = inputText; *tp != '\0'; byte++)
55         {
56                 if (tp[0] != '\\')
57                         tp++;
58                 else if ((tp[0] == '\\') &&
59                                  (tp[1] >= '0' && tp[1] <= '3') &&
60                                  (tp[2] >= '0' && tp[2] <= '7') &&
61                                  (tp[3] >= '0' && tp[3] <= '7'))
62                         tp += 4;
63                 else if ((tp[0] == '\\') &&
64                                  (tp[1] == '\\'))
65                         tp += 2;
66                 else
67                 {
68                         /*
69                          * one backslash, not followed by 0 or ### valid octal
70                          */
71                         elog(ERROR, "Bad input string for type bytea");
72                 }
73         }
74
75         byte += VARHDRSZ;
76         result = (bytea *) palloc(byte);
77         result->vl_len = byte;          /* set varlena length */
78
79         tp = inputText;
80         rp = result->vl_dat;
81         while (*tp != '\0')
82         {
83                 if (tp[0] != '\\')
84                         *rp++ = *tp++;
85                 else if ((tp[0] == '\\') &&
86                                  (tp[1] >= '0' && tp[1] <= '3') &&
87                                  (tp[2] >= '0' && tp[2] <= '7') &&
88                                  (tp[3] >= '0' && tp[3] <= '7'))
89                 {
90                         byte = VAL(tp[1]);
91                         byte <<= 3;
92                         byte += VAL(tp[2]);
93                         byte <<= 3;
94                         *rp++ = byte + VAL(tp[3]);
95                         tp += 4;
96                 }
97                 else if ((tp[0] == '\\') &&
98                                  (tp[1] == '\\'))
99                 {
100                         *rp++ = '\\';
101                         tp += 2;
102                 }
103                 else
104                 {
105                         /*
106                          * We should never get here. The first pass should not allow
107                          * it.
108                          */
109                         elog(ERROR, "Bad input string for type bytea");
110                 }
111         }
112
113         PG_RETURN_BYTEA_P(result);
114 }
115
116 /*
117  *              byteaout                - converts to printable representation of byte array
118  *
119  *              Non-printable characters are inserted as '\nnn' (octal) and '\' as
120  *              '\\'.
121  *
122  *              NULL vlena should be an error--returning string with NULL for now.
123  */
124 Datum
125 byteaout(PG_FUNCTION_ARGS)
126 {
127         bytea      *vlena = PG_GETARG_BYTEA_P(0);
128         char       *result;
129         char       *vp;
130         char       *rp;
131         int                     val;                    /* holds unprintable chars */
132         int                     i;
133         int                     len;
134
135         len = 1;                                        /* empty string has 1 char */
136         vp = vlena->vl_dat;
137         for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++)
138         {
139                 if (*vp == '\\')
140                         len += 2;
141                 else if (isprint((unsigned char) *vp))
142                         len++;
143                 else
144                         len += 4;
145         }
146         rp = result = (char *) palloc(len);
147         vp = vlena->vl_dat;
148         for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++)
149         {
150                 if (*vp == '\\')
151                 {
152                         *rp++ = '\\';
153                         *rp++ = '\\';
154                 }
155                 else if (isprint((unsigned char) *vp))
156                         *rp++ = *vp;
157                 else
158                 {
159                         val = *vp;
160                         rp[0] = '\\';
161                         rp[3] = DIG(val & 07);
162                         val >>= 3;
163                         rp[2] = DIG(val & 07);
164                         val >>= 3;
165                         rp[1] = DIG(val & 03);
166                         rp += 4;
167                 }
168         }
169         *rp = '\0';
170         PG_RETURN_CSTRING(result);
171 }
172
173
174 /*
175  *              textin                  - converts "..." to internal representation
176  */
177 Datum
178 textin(PG_FUNCTION_ARGS)
179 {
180         char       *inputText = PG_GETARG_CSTRING(0);
181         text       *result;
182         int                     len;
183
184 #ifdef MULTIBYTE
185         char       *ermsg;
186 #endif
187
188         len = strlen(inputText) + VARHDRSZ;
189
190 #ifdef MULTIBYTE
191         if ((ermsg = pg_verifymbstr(inputText, len - VARHDRSZ)))
192                 elog(ERROR, "%s", ermsg);
193 #endif
194
195         result = (text *) palloc(len);
196         VARATT_SIZEP(result) = len;
197
198         memcpy(VARDATA(result), inputText, len - VARHDRSZ);
199
200 #ifdef CYR_RECODE
201         convertstr(VARDATA(result), len - VARHDRSZ, 0);
202 #endif
203
204         PG_RETURN_TEXT_P(result);
205 }
206
207 /*
208  *              textout                 - converts internal representation to "..."
209  */
210 Datum
211 textout(PG_FUNCTION_ARGS)
212 {
213         text       *t = PG_GETARG_TEXT_P(0);
214         int                     len;
215         char       *result;
216
217         len = VARSIZE(t) - VARHDRSZ;
218         result = (char *) palloc(len + 1);
219         memcpy(result, VARDATA(t), len);
220         result[len] = '\0';
221
222 #ifdef CYR_RECODE
223         convertstr(result, len, 1);
224 #endif
225
226         PG_RETURN_CSTRING(result);
227 }
228
229
230 /* ========== PUBLIC ROUTINES ========== */
231
232 /*
233  * textlen -
234  *        returns the logical length of a text*
235  *         (which is less than the VARSIZE of the text*)
236  */
237 Datum
238 textlen(PG_FUNCTION_ARGS)
239 {
240         text       *t = PG_GETARG_TEXT_P(0);
241
242 #ifdef MULTIBYTE
243         /* optimization for single byte encoding */
244         if (pg_database_encoding_max_length() <= 1)
245                 PG_RETURN_INT32(VARSIZE(t) - VARHDRSZ);
246
247         PG_RETURN_INT32(
248                 pg_mbstrlen_with_len(VARDATA(t), VARSIZE(t) - VARHDRSZ)
249                 );
250 #else
251         PG_RETURN_INT32(VARSIZE(t) - VARHDRSZ);
252 #endif
253 }
254
255 /*
256  * textoctetlen -
257  *        returns the physical length of a text*
258  *         (which is less than the VARSIZE of the text*)
259  */
260 Datum
261 textoctetlen(PG_FUNCTION_ARGS)
262 {
263         text    *arg = PG_GETARG_TEXT_P(0);
264
265         PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
266 }
267
268 /*
269  * textcat -
270  *        takes two text* and returns a text* that is the concatenation of
271  *        the two.
272  *
273  * Rewritten by Sapa, sapa@hq.icb.chel.su. 8-Jul-96.
274  * Updated by Thomas, Thomas.Lockhart@jpl.nasa.gov 1997-07-10.
275  * Allocate space for output in all cases.
276  * XXX - thomas 1997-07-10
277  */
278 Datum
279 textcat(PG_FUNCTION_ARGS)
280 {
281         text       *t1 = PG_GETARG_TEXT_P(0);
282         text       *t2 = PG_GETARG_TEXT_P(1);
283         int                     len1,
284                                 len2,
285                                 len;
286         text       *result;
287         char       *ptr;
288
289         len1 = (VARSIZE(t1) - VARHDRSZ);
290         if (len1 < 0)
291                 len1 = 0;
292
293         len2 = (VARSIZE(t2) - VARHDRSZ);
294         if (len2 < 0)
295                 len2 = 0;
296
297         len = len1 + len2 + VARHDRSZ;
298         result = (text *) palloc(len);
299
300         /* Set size of result string... */
301         VARATT_SIZEP(result) = len;
302
303         /* Fill data field of result string... */
304         ptr = VARDATA(result);
305         if (len1 > 0)
306                 memcpy(ptr, VARDATA(t1), len1);
307         if (len2 > 0)
308                 memcpy(ptr + len1, VARDATA(t2), len2);
309
310         PG_RETURN_TEXT_P(result);
311 }
312
313 /*
314  * text_substr()
315  * Return a substring starting at the specified position.
316  * - thomas 1997-12-31
317  *
318  * Input:
319  *      - string
320  *      - starting position (is one-based)
321  *      - string length
322  *
323  * If the starting position is zero or less, then return from the start of the string
324  *      adjusting the length to be consistent with the "negative start" per SQL92.
325  * If the length is less than zero, return the remaining string.
326  *
327  * Note that the arguments operate on octet length,
328  *      so not aware of multi-byte character sets.
329  *
330  * Added multi-byte support.
331  * - Tatsuo Ishii 1998-4-21
332  * Changed behavior if starting position is less than one to conform to SQL92 behavior.
333  * Formerly returned the entire string; now returns a portion.
334  * - Thomas Lockhart 1998-12-10
335  * Now uses faster TOAST-slicing interface
336  * - John Gray 2002-02-22
337  */
338 Datum
339 text_substr(PG_FUNCTION_ARGS)
340 {
341         text       *string;
342         int32           m = PG_GETARG_INT32(1);
343         int32           n = PG_GETARG_INT32(2);
344         int32       sm;
345         int32       sn;
346         int         eml = 1;
347 #ifdef MULTIBYTE
348         int                     i;
349         int                     len;
350         text       *ret;
351         char       *p;
352 #endif 
353
354         /*
355          * starting position before the start of the string? then offset into
356          * the string per SQL92 spec...
357          */
358         if (m < 1)
359         {
360                 n += (m - 1);
361                 m = 1;
362         }
363         /* Check for m > octet length is made in TOAST access routine */
364
365         /* m will now become a zero-based starting position */
366         sm = m - 1;
367         sn = n;
368
369 #ifdef MULTIBYTE
370         eml = pg_database_encoding_max_length ();
371
372         if (eml > 1)
373         {
374                 sm = 0;
375                 sn = (m + n) * eml + 3; /* +3 to avoid mb characters overhanging slice end */
376         }
377 #endif 
378
379         string = PG_GETARG_TEXT_P_SLICE (0, sm, sn);
380
381         if (eml == 1) 
382         {
383                 PG_RETURN_TEXT_P (string);
384         }
385 #ifndef MULTIBYTE
386         PG_RETURN_NULL();   /* notreached: suppress compiler warning */
387 #endif
388 #ifdef MULTIBYTE
389         len = pg_mbstrlen_with_len (VARDATA (string), sn - 3);
390
391         if (m > len)
392         {
393                 m = 1;
394                 n = 0;
395         }
396         m--;
397         if (((m + n) > len) || (n < 0))
398                 n = (len - m);
399
400         p = VARDATA(string);
401         for (i = 0; i < m; i++)
402                 p += pg_mblen(p);
403         m = p - VARDATA(string);
404         for (i = 0; i < n; i++)
405                 p += pg_mblen(p);
406         n = p - (VARDATA(string) + m);
407
408         ret = (text *) palloc(VARHDRSZ + n);
409         VARATT_SIZEP(ret) = VARHDRSZ + n;
410
411         memcpy(VARDATA(ret), VARDATA(string) + m, n);
412
413         PG_RETURN_TEXT_P(ret);
414 #endif
415 }
416
417 /*
418  * textpos -
419  *        Return the position of the specified substring.
420  *        Implements the SQL92 POSITION() function.
421  *        Ref: A Guide To The SQL Standard, Date & Darwen, 1997
422  * - thomas 1997-07-27
423  *
424  * Added multi-byte support.
425  * - Tatsuo Ishii 1998-4-21
426  */
427 Datum
428 textpos(PG_FUNCTION_ARGS)
429 {
430         text       *t1 = PG_GETARG_TEXT_P(0);
431         text       *t2 = PG_GETARG_TEXT_P(1);
432         int                     pos;
433         int                     px,
434                                 p;
435         int                     len1,
436                                 len2;
437         pg_wchar   *p1,
438                            *p2;
439
440 #ifdef MULTIBYTE
441         pg_wchar   *ps1,
442                            *ps2;
443 #endif
444
445         if (VARSIZE(t2) <= VARHDRSZ)
446                 PG_RETURN_INT32(1);             /* result for empty pattern */
447
448         len1 = (VARSIZE(t1) - VARHDRSZ);
449         len2 = (VARSIZE(t2) - VARHDRSZ);
450 #ifdef MULTIBYTE
451         ps1 = p1 = (pg_wchar *) palloc((len1 + 1) * sizeof(pg_wchar));
452         (void) pg_mb2wchar_with_len((unsigned char *) VARDATA(t1), p1, len1);
453         len1 = pg_wchar_strlen(p1);
454         ps2 = p2 = (pg_wchar *) palloc((len2 + 1) * sizeof(pg_wchar));
455         (void) pg_mb2wchar_with_len((unsigned char *) VARDATA(t2), p2, len2);
456         len2 = pg_wchar_strlen(p2);
457 #else
458         p1 = VARDATA(t1);
459         p2 = VARDATA(t2);
460 #endif
461         pos = 0;
462         px = (len1 - len2);
463         for (p = 0; p <= px; p++)
464         {
465 #ifdef MULTIBYTE
466                 if ((*p2 == *p1) && (pg_wchar_strncmp(p1, p2, len2) == 0))
467 #else
468                 if ((*p2 == *p1) && (strncmp(p1, p2, len2) == 0))
469 #endif
470                 {
471                         pos = p + 1;
472                         break;
473                 };
474                 p1++;
475         };
476 #ifdef MULTIBYTE
477         pfree(ps1);
478         pfree(ps2);
479 #endif
480         PG_RETURN_INT32(pos);
481 }
482
483 /* varstr_cmp()
484  * Comparison function for text strings with given lengths.
485  * Includes locale support, but must copy strings to temporary memory
486  *      to allow null-termination for inputs to strcoll().
487  * Returns -1, 0 or 1
488  */
489 int
490 varstr_cmp(char *arg1, int len1, char *arg2, int len2)
491 {
492         int                     result;
493         char       *a1p,
494                            *a2p;
495
496 #ifdef USE_LOCALE
497         a1p = (char *) palloc(len1 + 1);
498         a2p = (char *) palloc(len2 + 1);
499
500         memcpy(a1p, arg1, len1);
501         *(a1p + len1) = '\0';
502         memcpy(a2p, arg2, len2);
503         *(a2p + len2) = '\0';
504
505         result = strcoll(a1p, a2p);
506
507         pfree(a1p);
508         pfree(a2p);
509
510 #else
511
512         a1p = arg1;
513         a2p = arg2;
514
515         result = strncmp(a1p, a2p, Min(len1, len2));
516         if ((result == 0) && (len1 != len2))
517                 result = (len1 < len2) ? -1 : 1;
518 #endif
519
520         return result;
521 }
522
523
524 /* text_cmp()
525  * Internal comparison function for text strings.
526  * Returns -1, 0 or 1
527  */
528 static int
529 text_cmp(text *arg1, text *arg2)
530 {
531         char       *a1p,
532                            *a2p;
533         int                     len1,
534                                 len2;
535
536         a1p = VARDATA(arg1);
537         a2p = VARDATA(arg2);
538
539         len1 = VARSIZE(arg1) - VARHDRSZ;
540         len2 = VARSIZE(arg2) - VARHDRSZ;
541
542         return varstr_cmp(a1p, len1, a2p, len2);
543 }
544
545 /*
546  * Comparison functions for text strings.
547  *
548  * Note: btree indexes need these routines not to leak memory; therefore,
549  * be careful to free working copies of toasted datums.  Most places don't
550  * need to be so careful.
551  */
552
553 Datum
554 texteq(PG_FUNCTION_ARGS)
555 {
556         text       *arg1 = PG_GETARG_TEXT_P(0);
557         text       *arg2 = PG_GETARG_TEXT_P(1);
558         bool            result;
559
560         /* fast path for different-length inputs */
561         if (VARSIZE(arg1) != VARSIZE(arg2))
562                 result = false;
563         else
564                 result = (text_cmp(arg1, arg2) == 0);
565
566         PG_FREE_IF_COPY(arg1, 0);
567         PG_FREE_IF_COPY(arg2, 1);
568
569         PG_RETURN_BOOL(result);
570 }
571
572 Datum
573 textne(PG_FUNCTION_ARGS)
574 {
575         text       *arg1 = PG_GETARG_TEXT_P(0);
576         text       *arg2 = PG_GETARG_TEXT_P(1);
577         bool            result;
578
579         /* fast path for different-length inputs */
580         if (VARSIZE(arg1) != VARSIZE(arg2))
581                 result = true;
582         else
583                 result = (text_cmp(arg1, arg2) != 0);
584
585         PG_FREE_IF_COPY(arg1, 0);
586         PG_FREE_IF_COPY(arg2, 1);
587
588         PG_RETURN_BOOL(result);
589 }
590
591 Datum
592 text_lt(PG_FUNCTION_ARGS)
593 {
594         text       *arg1 = PG_GETARG_TEXT_P(0);
595         text       *arg2 = PG_GETARG_TEXT_P(1);
596         bool            result;
597
598         result = (text_cmp(arg1, arg2) < 0);
599
600         PG_FREE_IF_COPY(arg1, 0);
601         PG_FREE_IF_COPY(arg2, 1);
602
603         PG_RETURN_BOOL(result);
604 }
605
606 Datum
607 text_le(PG_FUNCTION_ARGS)
608 {
609         text       *arg1 = PG_GETARG_TEXT_P(0);
610         text       *arg2 = PG_GETARG_TEXT_P(1);
611         bool            result;
612
613         result = (text_cmp(arg1, arg2) <= 0);
614
615         PG_FREE_IF_COPY(arg1, 0);
616         PG_FREE_IF_COPY(arg2, 1);
617
618         PG_RETURN_BOOL(result);
619 }
620
621 Datum
622 text_gt(PG_FUNCTION_ARGS)
623 {
624         text       *arg1 = PG_GETARG_TEXT_P(0);
625         text       *arg2 = PG_GETARG_TEXT_P(1);
626         bool            result;
627
628         result = (text_cmp(arg1, arg2) > 0);
629
630         PG_FREE_IF_COPY(arg1, 0);
631         PG_FREE_IF_COPY(arg2, 1);
632
633         PG_RETURN_BOOL(result);
634 }
635
636 Datum
637 text_ge(PG_FUNCTION_ARGS)
638 {
639         text       *arg1 = PG_GETARG_TEXT_P(0);
640         text       *arg2 = PG_GETARG_TEXT_P(1);
641         bool            result;
642
643         result = (text_cmp(arg1, arg2) >= 0);
644
645         PG_FREE_IF_COPY(arg1, 0);
646         PG_FREE_IF_COPY(arg2, 1);
647
648         PG_RETURN_BOOL(result);
649 }
650
651 Datum
652 bttextcmp(PG_FUNCTION_ARGS)
653 {
654         text       *arg1 = PG_GETARG_TEXT_P(0);
655         text       *arg2 = PG_GETARG_TEXT_P(1);
656         int32           result;
657
658         result = text_cmp(arg1, arg2);
659
660         PG_FREE_IF_COPY(arg1, 0);
661         PG_FREE_IF_COPY(arg2, 1);
662
663         PG_RETURN_INT32(result);
664 }
665
666
667 Datum
668 text_larger(PG_FUNCTION_ARGS)
669 {
670         text       *arg1 = PG_GETARG_TEXT_P(0);
671         text       *arg2 = PG_GETARG_TEXT_P(1);
672         text       *result;
673
674         result = ((text_cmp(arg1, arg2) > 0) ? arg1 : arg2);
675
676         PG_RETURN_TEXT_P(result);
677 }
678
679 Datum
680 text_smaller(PG_FUNCTION_ARGS)
681 {
682         text       *arg1 = PG_GETARG_TEXT_P(0);
683         text       *arg2 = PG_GETARG_TEXT_P(1);
684         text       *result;
685
686         result = ((text_cmp(arg1, arg2) < 0) ? arg1 : arg2);
687
688         PG_RETURN_TEXT_P(result);
689 }
690
691 /*-------------------------------------------------------------
692  * byteaoctetlen
693  *
694  * get the number of bytes contained in an instance of type 'bytea'
695  *-------------------------------------------------------------
696  */
697 Datum
698 byteaoctetlen(PG_FUNCTION_ARGS)
699 {
700         bytea      *v = PG_GETARG_BYTEA_P(0);
701
702         PG_RETURN_INT32(VARSIZE(v) - VARHDRSZ);
703 }
704
705 /*
706  * byteacat -
707  *        takes two bytea* and returns a bytea* that is the concatenation of
708  *        the two.
709  *
710  * Cloned from textcat and modified as required.
711  */
712 Datum
713 byteacat(PG_FUNCTION_ARGS)
714 {
715         bytea      *t1 = PG_GETARG_BYTEA_P(0);
716         bytea      *t2 = PG_GETARG_BYTEA_P(1);
717         int                     len1,
718                                 len2,
719                                 len;
720         bytea      *result;
721         char       *ptr;
722
723         len1 = (VARSIZE(t1) - VARHDRSZ);
724         if (len1 < 0)
725                 len1 = 0;
726
727         len2 = (VARSIZE(t2) - VARHDRSZ);
728         if (len2 < 0)
729                 len2 = 0;
730
731         len = len1 + len2 + VARHDRSZ;
732         result = (bytea *) palloc(len);
733
734         /* Set size of result string... */
735         VARATT_SIZEP(result) = len;
736
737         /* Fill data field of result string... */
738         ptr = VARDATA(result);
739         if (len1 > 0)
740                 memcpy(ptr, VARDATA(t1), len1);
741         if (len2 > 0)
742                 memcpy(ptr + len1, VARDATA(t2), len2);
743
744         PG_RETURN_BYTEA_P(result);
745 }
746
747 /*
748  * bytea_substr()
749  * Return a substring starting at the specified position.
750  * Cloned from text_substr and modified as required.
751  *
752  * Input:
753  *      - string
754  *      - starting position (is one-based)
755  *      - string length
756  *
757  * If the starting position is zero or less, then return from the start of the string
758  * adjusting the length to be consistent with the "negative start" per SQL92.
759  * If the length is less than zero, return the remaining string.
760  *
761  */
762 Datum
763 bytea_substr(PG_FUNCTION_ARGS)
764 {
765         int32           m = PG_GETARG_INT32(1);
766         int32           n = PG_GETARG_INT32(2);
767
768         /*
769          * starting position before the start of the string? then offset into
770          * the string per SQL92 spec...
771          */
772         if (m < 1)
773         {
774                 n += (m - 1);
775                 m = 1;
776         }
777
778         /* m will now become a zero-based starting position */
779         m--;
780
781         PG_RETURN_BYTEA_P(PG_GETARG_BYTEA_P_SLICE (0, m, n));
782 }
783
784 /*
785  * byteapos -
786  *        Return the position of the specified substring.
787  *        Implements the SQL92 POSITION() function.
788  * Cloned from textpos and modified as required.
789  */
790 Datum
791 byteapos(PG_FUNCTION_ARGS)
792 {
793         bytea      *t1 = PG_GETARG_BYTEA_P(0);
794         bytea      *t2 = PG_GETARG_BYTEA_P(1);
795         int                     pos;
796         int                     px,
797                                 p;
798         int                     len1,
799                                 len2;
800         char       *p1,
801                            *p2;
802
803         if (VARSIZE(t2) <= VARHDRSZ)
804                 PG_RETURN_INT32(1);             /* result for empty pattern */
805
806         len1 = (VARSIZE(t1) - VARHDRSZ);
807         len2 = (VARSIZE(t2) - VARHDRSZ);
808
809         p1 = VARDATA(t1);
810         p2 = VARDATA(t2);
811
812         pos = 0;
813         px = (len1 - len2);
814         for (p = 0; p <= px; p++)
815         {
816                 if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
817                 {
818                         pos = p + 1;
819                         break;
820                 };
821                 p1++;
822         };
823
824         PG_RETURN_INT32(pos);
825 }
826
827 /*-------------------------------------------------------------
828  * byteaGetByte
829  *
830  * this routine treats "bytea" as an array of bytes.
831  * It returns the Nth byte (a number between 0 and 255).
832  *-------------------------------------------------------------
833  */
834 Datum
835 byteaGetByte(PG_FUNCTION_ARGS)
836 {
837         bytea      *v = PG_GETARG_BYTEA_P(0);
838         int32           n = PG_GETARG_INT32(1);
839         int                     len;
840         int                     byte;
841
842         len = VARSIZE(v) - VARHDRSZ;
843
844         if (n < 0 || n >= len)
845                 elog(ERROR, "byteaGetByte: index %d out of range [0..%d]",
846                          n, len - 1);
847
848         byte = ((unsigned char *) VARDATA(v))[n];
849
850         PG_RETURN_INT32(byte);
851 }
852
853 /*-------------------------------------------------------------
854  * byteaGetBit
855  *
856  * This routine treats a "bytea" type like an array of bits.
857  * It returns the value of the Nth bit (0 or 1).
858  *
859  *-------------------------------------------------------------
860  */
861 Datum
862 byteaGetBit(PG_FUNCTION_ARGS)
863 {
864         bytea      *v = PG_GETARG_BYTEA_P(0);
865         int32           n = PG_GETARG_INT32(1);
866         int                     byteNo,
867                                 bitNo;
868         int                     len;
869         int                     byte;
870
871         len = VARSIZE(v) - VARHDRSZ;
872
873         if (n < 0 || n >= len * 8)
874                 elog(ERROR, "byteaGetBit: index %d out of range [0..%d]",
875                          n, len * 8 - 1);
876
877         byteNo = n / 8;
878         bitNo = n % 8;
879
880         byte = ((unsigned char *) VARDATA(v))[byteNo];
881
882         if (byte & (1 << bitNo))
883                 PG_RETURN_INT32(1);
884         else
885                 PG_RETURN_INT32(0);
886 }
887
888 /*-------------------------------------------------------------
889  * byteaSetByte
890  *
891  * Given an instance of type 'bytea' creates a new one with
892  * the Nth byte set to the given value.
893  *
894  *-------------------------------------------------------------
895  */
896 Datum
897 byteaSetByte(PG_FUNCTION_ARGS)
898 {
899         bytea      *v = PG_GETARG_BYTEA_P(0);
900         int32           n = PG_GETARG_INT32(1);
901         int32           newByte = PG_GETARG_INT32(2);
902         int                     len;
903         bytea      *res;
904
905         len = VARSIZE(v) - VARHDRSZ;
906
907         if (n < 0 || n >= len)
908                 elog(ERROR, "byteaSetByte: index %d out of range [0..%d]",
909                          n, len - 1);
910
911         /*
912          * Make a copy of the original varlena.
913          */
914         res = (bytea *) palloc(VARSIZE(v));
915         memcpy((char *) res, (char *) v, VARSIZE(v));
916
917         /*
918          * Now set the byte.
919          */
920         ((unsigned char *) VARDATA(res))[n] = newByte;
921
922         PG_RETURN_BYTEA_P(res);
923 }
924
925 /*-------------------------------------------------------------
926  * byteaSetBit
927  *
928  * Given an instance of type 'bytea' creates a new one with
929  * the Nth bit set to the given value.
930  *
931  *-------------------------------------------------------------
932  */
933 Datum
934 byteaSetBit(PG_FUNCTION_ARGS)
935 {
936         bytea      *v = PG_GETARG_BYTEA_P(0);
937         int32           n = PG_GETARG_INT32(1);
938         int32           newBit = PG_GETARG_INT32(2);
939         bytea      *res;
940         int                     len;
941         int                     oldByte,
942                                 newByte;
943         int                     byteNo,
944                                 bitNo;
945
946         len = VARSIZE(v) - VARHDRSZ;
947
948         if (n < 0 || n >= len * 8)
949                 elog(ERROR, "byteaSetBit: index %d out of range [0..%d]",
950                          n, len * 8 - 1);
951
952         byteNo = n / 8;
953         bitNo = n % 8;
954
955         /*
956          * sanity check!
957          */
958         if (newBit != 0 && newBit != 1)
959                 elog(ERROR, "byteaSetBit: new bit must be 0 or 1");
960
961         /*
962          * Make a copy of the original varlena.
963          */
964         res = (bytea *) palloc(VARSIZE(v));
965         memcpy((char *) res, (char *) v, VARSIZE(v));
966
967         /*
968          * Update the byte.
969          */
970         oldByte = ((unsigned char *) VARDATA(res))[byteNo];
971
972         if (newBit == 0)
973                 newByte = oldByte & (~(1 << bitNo));
974         else
975                 newByte = oldByte | (1 << bitNo);
976
977         ((unsigned char *) VARDATA(res))[byteNo] = newByte;
978
979         PG_RETURN_BYTEA_P(res);
980 }
981
982
983 /* text_name()
984  * Converts a text type to a Name type.
985  */
986 Datum
987 text_name(PG_FUNCTION_ARGS)
988 {
989         text       *s = PG_GETARG_TEXT_P(0);
990         Name            result;
991         int                     len;
992
993         len = VARSIZE(s) - VARHDRSZ;
994
995         /* Truncate oversize input */
996         if (len >= NAMEDATALEN)
997                 len = NAMEDATALEN - 1;
998
999 #ifdef STRINGDEBUG
1000         printf("text- convert string length %d (%d) ->%d\n",
1001                    VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
1002 #endif
1003
1004         result = (Name) palloc(NAMEDATALEN);
1005         memcpy(NameStr(*result), VARDATA(s), len);
1006
1007         /* now null pad to full length... */
1008         while (len < NAMEDATALEN)
1009         {
1010                 *(NameStr(*result) + len) = '\0';
1011                 len++;
1012         }
1013
1014         PG_RETURN_NAME(result);
1015 }
1016
1017 /* name_text()
1018  * Converts a Name type to a text type.
1019  */
1020 Datum
1021 name_text(PG_FUNCTION_ARGS)
1022 {
1023         Name            s = PG_GETARG_NAME(0);
1024         text       *result;
1025         int                     len;
1026
1027         len = strlen(NameStr(*s));
1028
1029 #ifdef STRINGDEBUG
1030         printf("text- convert string length %d (%d) ->%d\n",
1031                    VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
1032 #endif
1033
1034         result = palloc(VARHDRSZ + len);
1035         VARATT_SIZEP(result) = VARHDRSZ + len;
1036         memcpy(VARDATA(result), NameStr(*s), len);
1037
1038         PG_RETURN_TEXT_P(result);
1039 }
1040
1041
1042 /*
1043  * textToQualifiedNameList - convert a text object to list of names
1044  *
1045  * This implements the input parsing needed by nextval() and other
1046  * functions that take a text parameter representing a qualified name.
1047  * We split the name at dots, downcase if not double-quoted, and
1048  * truncate names if they're too long.
1049  */
1050 List *
1051 textToQualifiedNameList(text *textval, const char *caller)
1052 {
1053         char       *rawname;
1054         List       *result = NIL;
1055         List       *namelist;
1056         List       *l;
1057
1058         /* Convert to C string (handles possible detoasting). */
1059         /* Note we rely on being able to modify rawname below. */
1060         rawname = DatumGetCString(DirectFunctionCall1(textout,
1061                                                                                                   PointerGetDatum(textval)));
1062
1063         if (!SplitIdentifierString(rawname, '.', &namelist))
1064                 elog(ERROR, "%s: invalid name syntax", caller);
1065
1066         if (namelist == NIL)
1067                 elog(ERROR, "%s: invalid name syntax", caller);
1068
1069         foreach(l, namelist)
1070         {
1071                 char   *curname = (char *) lfirst(l);
1072
1073                 result = lappend(result, makeString(pstrdup(curname)));
1074         }
1075
1076         pfree(rawname);
1077         freeList(namelist);
1078
1079         return result;
1080 }
1081
1082 /*
1083  * SplitIdentifierString --- parse a string containing identifiers
1084  *
1085  * This is the guts of textToQualifiedNameList, and is exported for use in
1086  * other situations such as parsing GUC variables.  In the GUC case, it's
1087  * important to avoid memory leaks, so the API is designed to minimize the
1088  * amount of stuff that needs to be allocated and freed.
1089  *
1090  * Inputs:
1091  *      rawstring: the input string; must be overwritable!  On return, it's
1092  *                         been modified to contain the separated identifiers.
1093  *      separator: the separator punctuation expected between identifiers
1094  *                         (typically '.' or ',').  Whitespace may also appear around
1095  *                         identifiers.
1096  * Outputs:
1097  *      namelist: filled with a palloc'd list of pointers to identifiers within
1098  *                        rawstring.  Caller should freeList() this even on error return.
1099  *
1100  * Returns TRUE if okay, FALSE if there is a syntax error in the string.
1101  *
1102  * Note that an empty string is considered okay here, though not in
1103  * textToQualifiedNameList.
1104  */
1105 bool
1106 SplitIdentifierString(char *rawstring, char separator,
1107                                           List **namelist)
1108 {
1109         char       *nextp = rawstring;
1110         bool            done = false;
1111
1112         *namelist = NIL;
1113
1114         while (isspace((unsigned char) *nextp))
1115                 nextp++;                                /* skip leading whitespace */
1116
1117         if (*nextp == '\0')
1118                 return true;                    /* allow empty string */
1119
1120         /* At the top of the loop, we are at start of a new identifier. */
1121         do
1122         {
1123                 char       *curname;
1124                 char       *endp;
1125                 int                     curlen;
1126
1127                 if (*nextp == '\"')
1128                 {
1129                         /* Quoted name --- collapse quote-quote pairs, no downcasing */
1130                         curname = nextp + 1;
1131                         for (;;)
1132                         {
1133                                 endp = strchr(nextp + 1, '\"');
1134                                 if (endp == NULL)
1135                                         return false; /* mismatched quotes */
1136                                 if (endp[1] != '\"')
1137                                         break;          /* found end of quoted name */
1138                                 /* Collapse adjacent quotes into one quote, and look again */
1139                                 memmove(endp, endp+1, strlen(endp));
1140                                 nextp = endp;
1141                         }
1142                         /* endp now points at the terminating quote */
1143                         nextp = endp + 1;
1144                 }
1145                 else
1146                 {
1147                         /* Unquoted name --- extends to separator or whitespace */
1148                         curname = nextp;
1149                         while (*nextp && *nextp != separator &&
1150                                    !isspace((unsigned char) *nextp))
1151                         {
1152                                 /*
1153                                  * It's important that this match the identifier downcasing
1154                                  * code used by backend/parser/scan.l.
1155                                  */
1156                                 if (isupper((unsigned char) *nextp))
1157                                         *nextp = tolower((unsigned char) *nextp);
1158                                 nextp++;
1159                         }
1160                         endp = nextp;
1161                         if (curname == nextp)
1162                                 return false;   /* empty unquoted name not allowed */
1163                 }
1164
1165                 while (isspace((unsigned char) *nextp))
1166                         nextp++;                        /* skip trailing whitespace */
1167
1168                 if (*nextp == separator)
1169                 {
1170                         nextp++;
1171                         while (isspace((unsigned char) *nextp))
1172                                 nextp++;                /* skip leading whitespace for next */
1173                         /* we expect another name, so done remains false */
1174                 }
1175                 else if (*nextp == '\0')
1176                         done = true;
1177                 else
1178                         return false;           /* invalid syntax */
1179
1180                 /* Now safe to overwrite separator with a null */
1181                 *endp = '\0';
1182
1183                 /* Truncate name if it's overlength; again, should match scan.l */
1184                 curlen = strlen(curname);
1185                 if (curlen >= NAMEDATALEN)
1186                 {
1187 #ifdef MULTIBYTE
1188                         curlen = pg_mbcliplen(curname, curlen, NAMEDATALEN - 1);
1189                         curname[curlen] = '\0';
1190 #else
1191                         curname[NAMEDATALEN - 1] = '\0';
1192 #endif
1193                 }
1194
1195                 /*
1196                  * Finished isolating current name --- add it to list
1197                  */
1198                 *namelist = lappend(*namelist, curname);
1199
1200                 /* Loop back if we didn't reach end of string */
1201         } while (!done);
1202
1203         return true;
1204 }
1205
1206
1207 /*****************************************************************************
1208  *      Comparison Functions used for bytea
1209  *
1210  * Note: btree indexes need these routines not to leak memory; therefore,
1211  * be careful to free working copies of toasted datums.  Most places don't
1212  * need to be so careful.
1213  *****************************************************************************/
1214
1215 Datum
1216 byteaeq(PG_FUNCTION_ARGS)
1217 {
1218         bytea      *arg1 = PG_GETARG_BYTEA_P(0);
1219         bytea      *arg2 = PG_GETARG_BYTEA_P(1);
1220         int                     len1,
1221                                 len2;
1222         bool            result;
1223
1224         len1 = VARSIZE(arg1) - VARHDRSZ;
1225         len2 = VARSIZE(arg2) - VARHDRSZ;
1226
1227         /* fast path for different-length inputs */
1228         if (len1 != len2)
1229                 result = false;
1230         else
1231                 result = (memcmp(VARDATA(arg1), VARDATA(arg2), len1) == 0);
1232
1233         PG_FREE_IF_COPY(arg1, 0);
1234         PG_FREE_IF_COPY(arg2, 1);
1235
1236         PG_RETURN_BOOL(result);
1237 }
1238
1239 Datum
1240 byteane(PG_FUNCTION_ARGS)
1241 {
1242         bytea      *arg1 = PG_GETARG_BYTEA_P(0);
1243         bytea      *arg2 = PG_GETARG_BYTEA_P(1);
1244         int                     len1,
1245                                 len2;
1246         bool            result;
1247
1248         len1 = VARSIZE(arg1) - VARHDRSZ;
1249         len2 = VARSIZE(arg2) - VARHDRSZ;
1250
1251         /* fast path for different-length inputs */
1252         if (len1 != len2)
1253                 result = true;
1254         else
1255                 result = (memcmp(VARDATA(arg1), VARDATA(arg2), len1) != 0);
1256
1257         PG_FREE_IF_COPY(arg1, 0);
1258         PG_FREE_IF_COPY(arg2, 1);
1259
1260         PG_RETURN_BOOL(result);
1261 }
1262
1263 Datum
1264 bytealt(PG_FUNCTION_ARGS)
1265 {
1266         bytea      *arg1 = PG_GETARG_BYTEA_P(0);
1267         bytea      *arg2 = PG_GETARG_BYTEA_P(1);
1268         int                     len1,
1269                                 len2;
1270         int                     cmp;
1271
1272         len1 = VARSIZE(arg1) - VARHDRSZ;
1273         len2 = VARSIZE(arg2) - VARHDRSZ;
1274
1275         cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
1276
1277         PG_FREE_IF_COPY(arg1, 0);
1278         PG_FREE_IF_COPY(arg2, 1);
1279
1280         PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
1281 }
1282
1283 Datum
1284 byteale(PG_FUNCTION_ARGS)
1285 {
1286         bytea      *arg1 = PG_GETARG_BYTEA_P(0);
1287         bytea      *arg2 = PG_GETARG_BYTEA_P(1);
1288         int                     len1,
1289                                 len2;
1290         int                     cmp;
1291
1292         len1 = VARSIZE(arg1) - VARHDRSZ;
1293         len2 = VARSIZE(arg2) - VARHDRSZ;
1294
1295         cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
1296
1297         PG_FREE_IF_COPY(arg1, 0);
1298         PG_FREE_IF_COPY(arg2, 1);
1299
1300         PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
1301 }
1302
1303 Datum
1304 byteagt(PG_FUNCTION_ARGS)
1305 {
1306         bytea      *arg1 = PG_GETARG_BYTEA_P(0);
1307         bytea      *arg2 = PG_GETARG_BYTEA_P(1);
1308         int                     len1,
1309                                 len2;
1310         int                     cmp;
1311
1312         len1 = VARSIZE(arg1) - VARHDRSZ;
1313         len2 = VARSIZE(arg2) - VARHDRSZ;
1314
1315         cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
1316
1317         PG_FREE_IF_COPY(arg1, 0);
1318         PG_FREE_IF_COPY(arg2, 1);
1319
1320         PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
1321 }
1322
1323 Datum
1324 byteage(PG_FUNCTION_ARGS)
1325 {
1326         bytea      *arg1 = PG_GETARG_BYTEA_P(0);
1327         bytea      *arg2 = PG_GETARG_BYTEA_P(1);
1328         int                     len1,
1329                                 len2;
1330         int                     cmp;
1331
1332         len1 = VARSIZE(arg1) - VARHDRSZ;
1333         len2 = VARSIZE(arg2) - VARHDRSZ;
1334
1335         cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
1336
1337         PG_FREE_IF_COPY(arg1, 0);
1338         PG_FREE_IF_COPY(arg2, 1);
1339
1340         PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
1341 }
1342
1343 Datum
1344 byteacmp(PG_FUNCTION_ARGS)
1345 {
1346         bytea      *arg1 = PG_GETARG_BYTEA_P(0);
1347         bytea      *arg2 = PG_GETARG_BYTEA_P(1);
1348         int                     len1,
1349                                 len2;
1350         int                     cmp;
1351
1352         len1 = VARSIZE(arg1) - VARHDRSZ;
1353         len2 = VARSIZE(arg2) - VARHDRSZ;
1354
1355         cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
1356         if ((cmp == 0) && (len1 != len2))
1357                 cmp = (len1 < len2) ? -1 : 1;
1358
1359         PG_FREE_IF_COPY(arg1, 0);
1360         PG_FREE_IF_COPY(arg2, 1);
1361
1362         PG_RETURN_INT32(cmp);
1363 }