Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8cdabf0

Browse files
author
Thomas G. Lockhart
committed
Augment the function call map logic with code from Tom Lane.
Should be more robust to overflows. Pass through an unmapped function unchanged, rather than rejecting it.Add a few more functions, but comment out those which can go through as-is.Can be used with contrib/odbc/ package, though that isn't committed yet.
1 parent51cfdae commit8cdabf0

File tree

1 file changed

+129
-37
lines changed

1 file changed

+129
-37
lines changed

‎src/interfaces/odbc/convert.c

Lines changed: 129 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,76 @@ typedef signed char SCHAR;
5858

5959
externGLOBAL_VALUESglobals;
6060

61-
/*How to map ODBC scalar functions {fn func(args)} to Postgres */
62-
/*This is just a simple substitution */
63-
char*mapFuncs[][2]= {
64-
{"CONCAT","textcat" },
65-
{"LCASE","lower" },
66-
{"LOCATE","strpos" },
67-
{"LENGTH","textlen" },
68-
{"LTRIM","ltrim" },
69-
{"RTRIM","rtrim" },
70-
{"SUBSTRING","substr" },
71-
{"UCASE","upper" },
72-
{"NOW","now" },
73-
{0,0 }
61+
/*How to map ODBC scalar functions {fn func(args)} to Postgres
62+
*This is just a simple substitution
63+
*List augmented from
64+
* http://www.merant.com/datadirect/download/docs/odbc16/Odbcref/rappc.htm
65+
* - thomas 2000-04-03
66+
*/
67+
char*mapFuncs[][2]= {
68+
//{ "ASCII", "ascii" },
69+
{"CHAR","ichar" },
70+
{"CONCAT","textcat" },
71+
//{ "DIFFERENCE", "difference" },
72+
//{ "INSERT", "insert" },
73+
{"LCASE","lower" },
74+
{"LEFT","ltrunc" },
75+
{"LOCATE","strpos" },
76+
{"LENGTH","char_length"},
77+
//{ "LTRIM", "ltrim" },
78+
{"RIGHT","rtrunc" },
79+
//{ "REPEAT", "repeat" },
80+
//{ "REPLACE", "replace" },
81+
//{ "RTRIM", "rtrim" },
82+
//{ "SOUNDEX", "soundex" },
83+
{"SUBSTRING","substr" },
84+
{"UCASE","upper" },
85+
86+
//{ "ABS", "abs" },
87+
//{ "ACOS", "acos" },
88+
//{ "ASIN", "asin" },
89+
//{ "ATAN", "atan" },
90+
//{ "ATAN2", "atan2" },
91+
{"CEILING","ceil" },
92+
//{ "COS", "cos" },
93+
//{ "COT", "cot" },
94+
//{ "DEGREES", "degrees" },
95+
//{ "EXP", "exp" },
96+
//{ "FLOOR", "floor" },
97+
{"LOG","ln" },
98+
{"LOG10","log" },
99+
//{ "MOD", "mod" },
100+
//{ "PI", "pi" },
101+
{"POWER","pow" },
102+
//{ "RADIANS", "radians" },
103+
{"RAND","random" },
104+
//{ "ROUND", "round" },
105+
//{ "SIGN", "sign" },
106+
//{ "SIN", "sin" },
107+
//{ "SQRT", "sqrt" },
108+
//{ "TAN", "tan" },
109+
//{ "TRUNCATE", "truncate" },
110+
111+
//{ "CURDATE", "curdate" },
112+
//{ "CURTIME", "curtime" },
113+
//{ "DAYNAME", "dayname" },
114+
//{ "DAYOFMONTH", "dayofmonth" },
115+
//{ "DAYOFWEEK", "dayofweek" },
116+
//{ "DAYOFYEAR", "dayofyear" },
117+
//{ "HOUR", "hour" },
118+
//{ "MINUTE", "minute" },
119+
//{ "MONTH", "month" },
120+
//{ "MONTHNAME", "monthname" },
121+
//{ "NOW", "now" },
122+
//{ "QUARTER", "quarter" },
123+
//{ "SECOND", "second" },
124+
//{ "WEEK", "week" },
125+
//{ "YEAR", "year" },
126+
127+
//{ "DATABASE", "database" },
128+
{"IFNULL","coalesce" },
129+
{"USER","odbc_user" },
130+
{0,0 }
74131
};
75132

76133
char*mapFunction(char*func);
@@ -584,7 +641,7 @@ int
584641
copy_statement_with_parameters(StatementClass*stmt)
585642
{
586643
staticchar*func="copy_statement_with_parameters";
587-
unsignedintopos,npos;
644+
unsignedintopos,npos,oldstmtlen;
588645
charparam_string[128],tmp[256],cbuf[TEXT_FIELD_SIZE+5];
589646
intparam_number;
590647
Int2param_ctype,param_sqltype;
@@ -629,14 +686,17 @@ int lobj_fd, retval;
629686

630687
param_number=-1;
631688

632-
for (opos=0;opos<strlen(old_statement);opos++) {
689+
oldstmtlen=strlen(old_statement);
690+
691+
for (opos=0;opos<oldstmtlen;opos++) {
633692

634693
//Squeeze carriage-returns/linfeed pairs to linefeed only
635-
if (old_statement[opos]=='\r'&&opos+1<strlen(old_statement)&&old_statement[opos+1]=='\n') {
694+
if (old_statement[opos]=='\r'&&opos+1<oldstmtlen&&
695+
old_statement[opos+1]=='\n') {
636696
continue;
637697
}
638698

639-
//Handle literals (date, time, timestamp)
699+
//Handle literals (date, time, timestamp) and ODBC scalar functions
640700
elseif (old_statement[opos]=='{') {
641701
char*esc;
642702
char*begin=&old_statement[opos+1];
@@ -1056,37 +1116,69 @@ int i;
10561116
returnNULL;
10571117
}
10581118

1059-
//This function returns a pointer to static memory!
1119+
/* convert_escape()
1120+
* This function returns a pointer to static memory!
1121+
*/
10601122
char*
10611123
convert_escape(char*value)
10621124
{
1063-
charkey[32],val[256];
10641125
staticcharescape[1024];
1065-
charfunc[32],the_rest[1024];
1066-
char*mapFunc;
1067-
1068-
sscanf(value,"%s %[^\r]",key,val);
1126+
charkey[33];
10691127

1070-
mylog("convert_escape: key='%s', val='%s'\n",key,val);
1128+
/* Separate off the key, skipping leading and trailing whitespace */
1129+
while ((*value!='\0')&&isspace(*value))value++;
1130+
sscanf(value,"%32s",key);
1131+
while ((*value!='\0')&& (!isspace(*value)))value++;
1132+
while ((*value!='\0')&&isspace(*value))value++;
10711133

1072-
if ( !strcmp(key,"d")||
1073-
!strcmp(key,"t")||
1074-
!strcmp(key,"ts")) {
1134+
mylog("convert_escape: key='%s', val='%s'\n",key,value);
10751135

1076-
strcpy(escape,val);
1136+
if ( (strcmp(key,"d")==0)||
1137+
(strcmp(key,"t")==0)||
1138+
(strcmp(key,"ts")==0)) {
1139+
/* Literal; return the escape part as-is */
1140+
strncpy(escape,value,sizeof(escape)-1);
10771141
}
1078-
elseif ( !strcmp(key,"fn")) {
1079-
sscanf(val,"%[^(]%[^\r]",func,the_rest);
1080-
mapFunc=mapFunction(func);
1081-
if ( !mapFunc)
1082-
returnNULL;
1083-
else {
1084-
strcpy(escape,mapFunc);
1085-
strcat(escape,the_rest);
1142+
elseif (strcmp(key,"fn")==0) {
1143+
/* Function invocation
1144+
* Separate off the func name,
1145+
* skipping trailing whitespace.
1146+
*/
1147+
char*funcEnd=value;
1148+
charsvchar;
1149+
char*mapFunc;
1150+
1151+
while ((*funcEnd!='\0')&& (*funcEnd!='(')&&
1152+
(!isspace(*funcEnd)))funcEnd++;
1153+
svchar=*funcEnd;
1154+
*funcEnd='\0';
1155+
sscanf(value,"%32s",key);
1156+
*funcEnd=svchar;
1157+
while ((*funcEnd!='\0')&&isspace(*funcEnd))funcEnd++;
1158+
1159+
/* We expect left parenthensis here,
1160+
* else return fn body as-is since it is
1161+
* one of those "function constants".
1162+
*/
1163+
if (*funcEnd!='(') {
1164+
strncpy(escape,value,sizeof(escape)-1);
1165+
returnescape;
10861166
}
1087-
1167+
mapFunc=mapFunction(key);
1168+
/* We could have mapFunction() return key if not in table...
1169+
* - thomas 2000-04-03
1170+
*/
1171+
if (mapFunc==NULL) {
1172+
/* If unrecognized function name, return fn body as-is */
1173+
strncpy(escape,value,sizeof(escape)-1);
1174+
returnescape;
1175+
}
1176+
/* copy mapped name and remaining input string */
1177+
strcpy(escape,mapFunc);
1178+
strncat(escape,funcEnd,sizeof(escape)-strlen(mapFunc));
10881179
}
10891180
else {
1181+
/* Bogus key, leave untranslated */
10901182
returnNULL;
10911183
}
10921184

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp