1 /**********************************************************************
2  * PostgreSQL::InServer::Util
3  *
4  * src/pl/plperl/Util.xs
5  *
6  * Defines plperl interfaces for general-purpose utilities.
7  * This module is bootstrapped as soon as an interpreter is initialized.
8  * Currently doesn't define a PACKAGE= so all subs are in main:: to avoid
9  * the need for explicit importing.
10  *
11  **********************************************************************/
12 
13 /* this must be first: */
14 #include "postgres.h"
15 #include "fmgr.h"
16 #include "utils/builtins.h"
17 #include "utils/bytea.h"       /* for byteain & byteaout */
18 
19 /* Defined by Perl */
20 #undef _
21 
22 /* perl stuff */
23 #define PG_NEED_PERL_XSUB_H
24 #include "plperl.h"
25 #include "plperl_helpers.h"
26 
27 
28 static text *
sv2text(SV * sv)29 sv2text(SV *sv)
30 {
31 	char	   *str = sv2cstr(sv);
32 	text	   *text;
33 
34 	text = cstring_to_text(str);
35 	pfree(str);
36 	return text;
37 }
38 
39 MODULE = PostgreSQL::InServer::Util PREFIX = util_
40 
41 PROTOTYPES: ENABLE
42 VERSIONCHECK: DISABLE
43 
44 int
45 _aliased_constants()
46     PROTOTYPE:
47     ALIAS:
48         DEBUG   = DEBUG2
49         LOG     = LOG
50         INFO    = INFO
51         NOTICE  = NOTICE
52         WARNING = WARNING
53         ERROR   = ERROR
54     CODE:
55     /* uses the ALIAS value as the return value */
56     RETVAL = ix;
57     OUTPUT:
58     RETVAL
59 
60 
61 void
62 util_elog(level, msg)
63     int level
64     SV *msg
65     CODE:
66         if (level > ERROR)      /* no PANIC allowed thanks */
67             level = ERROR;
68         if (level < DEBUG5)
69             level = DEBUG5;
70         plperl_util_elog(level, msg);
71 
72 SV *
73 util_quote_literal(sv)
74     SV *sv
75     CODE:
76     if (!sv || !SvOK(sv)) {
77         RETVAL = &PL_sv_undef;
78     }
79     else {
80         text *arg = sv2text(sv);
81 		text *quoted = DatumGetTextP(DirectFunctionCall1(quote_literal, PointerGetDatum(arg)));
82 		char *str;
83 
84 		pfree(arg);
85 		str = text_to_cstring(quoted);
86 		RETVAL = cstr2sv(str);
87 		pfree(str);
88     }
89     OUTPUT:
90     RETVAL
91 
92 SV *
93 util_quote_nullable(sv)
94     SV *sv
95     CODE:
96     if (!sv || !SvOK(sv))
97 	{
98         RETVAL = cstr2sv("NULL");
99     }
100     else
101 	{
102         text *arg = sv2text(sv);
103 		text *quoted = DatumGetTextP(DirectFunctionCall1(quote_nullable, PointerGetDatum(arg)));
104 		char *str;
105 
106 		pfree(arg);
107 		str = text_to_cstring(quoted);
108 		RETVAL = cstr2sv(str);
109 		pfree(str);
110     }
111     OUTPUT:
112     RETVAL
113 
114 SV *
115 util_quote_ident(sv)
116     SV *sv
117     PREINIT:
118         text *arg;
119 		text *quoted;
120 		char *str;
121     CODE:
122         arg = sv2text(sv);
123 		quoted = DatumGetTextP(DirectFunctionCall1(quote_ident, PointerGetDatum(arg)));
124 
125 		pfree(arg);
126 		str = text_to_cstring(quoted);
127 		RETVAL = cstr2sv(str);
128 		pfree(str);
129     OUTPUT:
130     RETVAL
131 
132 SV *
133 util_decode_bytea(sv)
134     SV *sv
135     PREINIT:
136         char *arg;
137         text *ret;
138     CODE:
139         arg = SvPVbyte_nolen(sv);
140         ret = DatumGetTextP(DirectFunctionCall1(byteain, PointerGetDatum(arg)));
141         /* not cstr2sv because this is raw bytes not utf8'able */
142         RETVAL = newSVpvn(VARDATA(ret), (VARSIZE(ret) - VARHDRSZ));
143     OUTPUT:
144     RETVAL
145 
146 SV *
147 util_encode_bytea(sv)
148     SV *sv
149     PREINIT:
150         text *arg;
151         char *ret;
152 		STRLEN len;
153     CODE:
154         /* not sv2text because this is raw bytes not utf8'able */
155         ret = SvPVbyte(sv, len);
156 		arg = cstring_to_text_with_len(ret, len);
157         ret = DatumGetCString(DirectFunctionCall1(byteaout, PointerGetDatum(arg)));
158         RETVAL = cstr2sv(ret);
159     OUTPUT:
160     RETVAL
161 
162 SV *
163 looks_like_number(sv)
164     SV *sv
165     CODE:
166     if (!SvOK(sv))
167         RETVAL = &PL_sv_undef;
168     else if ( looks_like_number(sv) )
169         RETVAL = &PL_sv_yes;
170     else
171         RETVAL = &PL_sv_no;
172     OUTPUT:
173     RETVAL
174 
175 SV *
176 encode_typed_literal(sv, typname)
177 	SV 	   *sv
178 	char   *typname;
179 	PREINIT:
180 		char 	*outstr;
181 	CODE:
182 		outstr = plperl_sv_to_literal(sv, typname);
183 		if (outstr == NULL)
184 			RETVAL = &PL_sv_undef;
185 		else
186 			RETVAL = cstr2sv(outstr);
187 	OUTPUT:
188 	RETVAL
189 
190 BOOT:
191     items = 0;  /* avoid 'unused variable' warning */
192