24
24
#define QUALIFIED_METASTRING_H
25
25
26
26
#include " ../common/classes/MetaString.h"
27
+ #include " ../common/classes/objects_array.h"
27
28
#include " ../common/StatusArg.h"
28
29
#include < algorithm>
29
30
#include < cctype>
@@ -86,7 +87,7 @@ class BaseQualifiedName
86
87
}
87
88
88
89
public:
89
- static BaseQualifiedName<T> parseSchemaObject (const string& str)
90
+ static void parseSchemaObjectListNoSep (const string& str, ObjectsArray<BaseQualifiedName<T>>& list )
90
91
{
91
92
const auto isQuoted = [](const string& name) -> bool
92
93
{
@@ -118,6 +119,9 @@ class BaseQualifiedName
118
119
119
120
const auto validateUnquotedIdentifier = [&](const string& name)
120
121
{
122
+ if (name.length () > MAX_SQL_IDENTIFIER_LEN)
123
+ (Arg::Gds (isc_invalid_name) << str).raise ();
124
+
121
125
bool first = true ;
122
126
123
127
for (const auto c : name)
@@ -139,64 +143,137 @@ class BaseQualifiedName
139
143
return true ;
140
144
};
141
145
142
- BaseQualifiedName<T> result;
143
- string schema, object;
144
-
145
- // Find the last unquoted dot to determine schema and object
146
- bool inQuotes = false ;
147
- auto lastDotPos = string::npos;
146
+ size_t i = 0 ;
148
147
149
- for ( size_t i = 0 ; i < str. size (); ++i )
148
+ const auto skipSpaces = [&]( )
150
149
{
151
- if (str[i] == ' "' )
152
- inQuotes = !inQuotes;
153
- else if (str[i] == ' .' && !inQuotes)
154
- lastDotPos = i;
155
- }
150
+ while (i < str.size () &&
151
+ (str[i] == ' ' || str[i] == ' \t ' || str[i] == ' \f ' || str[i] == ' \r ' || str[i] == ' \n ' ))
152
+ {
153
+ ++i;
154
+ }
155
+ };
156
+
157
+ skipSpaces ();
156
158
157
- if (lastDotPos != string::npos)
159
+ do
158
160
{
159
- schema = str.substr (0 , lastDotPos);
160
- object = str.substr (lastDotPos + 1 );
161
- }
162
- else
163
- object = str;
161
+ BaseQualifiedName<T> result;
162
+ string schema, object;
164
163
165
- schema.trim (" \t\f\r\n " );
166
- object.trim (" \t\f\r\n " );
164
+ const auto start = i;
165
+ bool nameFound = false ;
166
+ bool inQuotes = false ;
167
+ auto dotPos = string::npos;
167
168
168
- // Process schema if it exists
169
- if (schema.hasData ())
170
- {
171
- if (isQuoted (schema))
172
- result.schema = unquote (schema);
169
+ for (; !nameFound && i < str.size (); ++i)
170
+ {
171
+ const auto ch = str[i];
172
+
173
+ if (inQuotes)
174
+ {
175
+ if (ch == ' "' )
176
+ {
177
+ if (i + 1 < str.size () && str[i + 1 ] == ' "' )
178
+ ++i;
179
+ else
180
+ inQuotes = false ;
181
+ }
182
+ }
183
+ else
184
+ {
185
+ switch (ch)
186
+ {
187
+ case ' "' :
188
+ inQuotes = true ;
189
+ break ;
190
+
191
+ case ' .' :
192
+ {
193
+ dotPos = i++;
194
+ skipSpaces ();
195
+ --i;
196
+ break ;
197
+ }
198
+
199
+ case ' ' :
200
+ case ' \t ' :
201
+ case ' \f ' :
202
+ case ' \r ' :
203
+ case ' \n ' :
204
+ {
205
+ skipSpaces ();
206
+
207
+ if (i < str.size () && str[i] == ' .' )
208
+ {
209
+ dotPos = i++;
210
+ skipSpaces ();
211
+ }
212
+ else
213
+ nameFound = true ;
214
+
215
+ --i;
216
+ break ;
217
+ }
218
+ }
219
+ }
220
+ }
221
+
222
+ if (dotPos != string::npos)
223
+ {
224
+ schema = str.substr (start, dotPos - start);
225
+ object = str.substr (dotPos + 1 , i - dotPos - 1 );
226
+ }
173
227
else
228
+ object = str.substr (start, i - start);
229
+
230
+ schema.trim (" \t\f\r\n " );
231
+ object.trim (" \t\f\r\n " );
232
+
233
+ // Process schema if it exists
234
+ if (schema.hasData ())
174
235
{
175
- validateUnquotedIdentifier (schema);
236
+ if (isQuoted (schema))
237
+ result.schema = unquote (schema);
238
+ else
239
+ {
240
+ validateUnquotedIdentifier (schema);
176
241
177
- std::transform (schema.begin (), schema.end (), schema.begin (), ::toupper);
178
- result.schema = schema;
242
+ std::transform (schema.begin (), schema.end (), schema.begin (), ::toupper);
243
+ result.schema = schema;
244
+ }
179
245
}
180
- }
181
246
182
- if (lastDotPos != string::npos && result.schema .isEmpty ())
183
- (Arg::Gds (isc_invalid_name) << str).raise ();
247
+ if (dotPos != string::npos && result.schema .isEmpty ())
248
+ (Arg::Gds (isc_invalid_name) << str).raise ();
184
249
185
- // Process object
186
- if (isQuoted (object))
187
- result.object = unquote (object);
188
- else
189
- {
190
- validateUnquotedIdentifier (object);
250
+ // Process object
251
+ if (isQuoted (object))
252
+ result.object = unquote (object);
253
+ else
254
+ {
255
+ validateUnquotedIdentifier (object);
256
+
257
+ std::transform (object.begin (), object.end (), object.begin (), ::toupper);
258
+ result.object = object;
259
+ }
260
+
261
+ if (result.object .isEmpty ())
262
+ (Arg::Gds (isc_invalid_name) << str).raise ();
191
263
192
- std::transform (object.begin (), object.end (), object.begin (), ::toupper);
193
- result.object = object;
194
- }
264
+ list.add (result);
265
+ } while (i < str.size ());
266
+ }
267
+
268
+ static BaseQualifiedName<T> parseSchemaObject (const string& str)
269
+ {
270
+ ObjectsArray<BaseQualifiedName<T>> list;
271
+ parseSchemaObjectListNoSep (str, list);
195
272
196
- if (result. object . isEmpty () )
273
+ if (list. getCount () != 1 )
197
274
(Arg::Gds (isc_invalid_name) << str).raise ();
198
275
199
- return result ;
276
+ return list[ 0 ] ;
200
277
}
201
278
202
279
public:
0 commit comments