00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "fennel/common/CommonPreamble.h"
00024 #include "fennel/calculator/ExtendedInstructionTable.h"
00025 #include "fennel/calculator/ExtendedInstructionContext.h"
00026 #include "fennel/calculator/SqlRegExp.h"
00027
00028 FENNEL_BEGIN_NAMESPACE
00029
00030
00031
00032 class ExtRegExpContext : public ExtendedInstructionContext
00033 {
00034 public:
00035 explicit
00036 ExtRegExpContext(
00037 boost::regex const & re,
00038 string const pat) :
00039 regex(re),
00040 pattern(pat)
00041 {
00042 }
00043 boost::regex regex;
00044 string pattern;
00045 };
00046
00047
00048 void
00049 strLikeEscapeA(
00050 boost::scoped_ptr<ExtendedInstructionContext>& context,
00051 RegisterRef<bool>* result,
00052 RegisterRef<char*>* matchValue,
00053 RegisterRef<char*>* pattern,
00054 RegisterRef<char*>* escape)
00055 {
00056 assert(StandardTypeDescriptor::isTextArray(matchValue->type()));
00057 assert(StandardTypeDescriptor::isTextArray(pattern->type()));
00058
00059
00060 if (matchValue->isNull() ||
00061 pattern->isNull() ||
00062 (escape ? escape->isNull() : false)) {
00063 result->toNull();
00064 result->length(0);
00065 } else {
00066 boost::regex* regexP;
00067 string* patP;
00068 ExtRegExpContext* ctxP;
00069
00070 ctxP = static_cast<ExtRegExpContext*>(context.get());
00071 if (!ctxP) {
00072 string pat;
00073 SqlLikePrep<1,1>(
00074 pattern->pointer(),
00075 pattern->length(),
00076 (escape ? escape->pointer() : 0),
00077 (escape ? escape->length() : 0),
00078 pat);
00079 try {
00080 boost::regex regex(pat);
00081 context.reset(new ExtRegExpContext(regex, pat));
00082 } catch (boost::bad_expression badexp) {
00083
00084
00085
00086 throw "22025";
00087 }
00088
00089 ctxP = static_cast<ExtRegExpContext*>(context.get());
00090 }
00091 regexP = &(ctxP->regex);
00092 patP = &(ctxP->pattern);
00093
00094 result->value(
00095 SqlRegExp<1,1>(
00096 matchValue->pointer(),
00097 matchValue->length(),
00098 pattern->length(),
00099 *regexP));
00100 }
00101 }
00102
00103 void
00104 strLikeA(
00105 boost::scoped_ptr<ExtendedInstructionContext>& context,
00106 RegisterRef<bool>* result,
00107 RegisterRef<char*>* matchValue,
00108 RegisterRef<char*>* pattern)
00109 {
00110 strLikeEscapeA(context, result, matchValue, pattern, 0);
00111 }
00112
00113
00114
00115 void
00116 strSimilarEscapeA(
00117 boost::scoped_ptr<ExtendedInstructionContext>& context,
00118 RegisterRef<bool>* result,
00119 RegisterRef<char*>* matchValue,
00120 RegisterRef<char*>* pattern,
00121 RegisterRef<char*>* escape)
00122 {
00123 assert(StandardTypeDescriptor::isTextArray(matchValue->type()));
00124 assert(StandardTypeDescriptor::isTextArray(pattern->type()));
00125
00126
00127 if (matchValue->isNull() ||
00128 pattern->isNull() ||
00129 (escape ? escape->isNull() : false)) {
00130 result->toNull();
00131 result->length(0);
00132 } else {
00133 boost::regex* regexP;
00134 string* patP;
00135 ExtRegExpContext* ctxP;
00136
00137 ctxP = static_cast<ExtRegExpContext*>(context.get());
00138 if (!ctxP) {
00139 string pat;
00140 SqlSimilarPrep<1,1>(
00141 pattern->pointer(),
00142 pattern->length(),
00143 (escape ? escape->pointer() : 0),
00144 (escape ? escape->length() : 0),
00145 pat);
00146 try {
00147 boost::regex regex(pat);
00148 context.reset(new ExtRegExpContext(regex, pat));
00149 } catch (boost::bad_expression badexp) {
00150
00151
00152 throw "2201B";
00153 }
00154
00155 ctxP = static_cast<ExtRegExpContext*>(context.get());
00156 }
00157 regexP = &(ctxP->regex);
00158 patP = &(ctxP->pattern);
00159
00160 result->value(
00161 SqlRegExp<1,1>(
00162 matchValue->pointer(),
00163 matchValue->length(),
00164 pattern->length(),
00165 *regexP));
00166 }
00167 }
00168
00169 void
00170 strSimilarA(
00171 boost::scoped_ptr<ExtendedInstructionContext>& context,
00172 RegisterRef<bool>* result,
00173 RegisterRef<char*>* matchValue,
00174 RegisterRef<char*>* pattern)
00175 {
00176 strSimilarEscapeA(context, result, matchValue, pattern, 0);
00177 }
00178
00179 void
00180 ExtRegExpRegister(ExtendedInstructionTable* eit)
00181 {
00182 assert(eit != NULL);
00183
00184
00185 int i;
00186 for (i = 0; i < 8; i++) {
00187 vector<StandardTypeDescriptorOrdinal> params;
00188
00189 params.push_back(STANDARD_TYPE_BOOL);
00190
00191 if (i & 0x01) {
00192 params.push_back(STANDARD_TYPE_CHAR);
00193 } else {
00194 params.push_back(STANDARD_TYPE_VARCHAR);
00195 }
00196 if (i & 0x02) {
00197 params.push_back(STANDARD_TYPE_CHAR);
00198 } else {
00199 params.push_back(STANDARD_TYPE_VARCHAR);
00200 }
00201
00202 eit->add(
00203 "strLikeA3", params,
00204 (ExtendedInstruction3Context<bool, char*, char*>*) NULL,
00205 &strLikeA);
00206 eit->add(
00207 "strSimilarA3", params,
00208 (ExtendedInstruction3Context<bool, char*, char*>*) NULL,
00209 &strSimilarA);
00210
00211
00212 if (i & 0x04) {
00213 params.push_back(STANDARD_TYPE_CHAR);
00214 } else {
00215 params.push_back(STANDARD_TYPE_VARCHAR);
00216 }
00217
00218 eit->add(
00219 "strLikeA4", params,
00220 (ExtendedInstruction4Context<bool, char*, char*, char*>*) NULL,
00221 &strLikeEscapeA);
00222 eit->add(
00223 "strSimilarA4", params,
00224 (ExtendedInstruction4Context<bool, char*, char*, char*>*) NULL,
00225 &strSimilarEscapeA);
00226 }
00227 }
00228
00229
00230 FENNEL_END_NAMESPACE
00231
00232