|
From: <asf...@us...> - 2015-07-27 01:06:53
|
Revision: 62047
http://sourceforge.net/p/firebird/code/62047
Author: asfernandes
Date: 2015-07-27 01:06:51 +0000 (Mon, 27 Jul 2015)
Log Message:
-----------
Fixed CORE-4881 - Increase maximum string literal length to 64K (bytes) while setting a lower limit (of characters) for multibyte charsets based on their max char. length (UTF-8 literals will be limited to 16383 characters).
Modified Paths:
--------------
firebird/trunk/lang_helpers/gds_codes.ftn
firebird/trunk/lang_helpers/gds_codes.pas
firebird/trunk/src/dsql/ExprNodes.cpp
firebird/trunk/src/dsql/Parser.cpp
firebird/trunk/src/dsql/gen.cpp
firebird/trunk/src/include/gen/codetext.h
firebird/trunk/src/include/gen/iberror.h
firebird/trunk/src/include/gen/msgs.h
firebird/trunk/src/include/gen/sql_code.h
firebird/trunk/src/include/gen/sql_state.h
firebird/trunk/src/jrd/DataTypeUtil.cpp
firebird/trunk/src/jrd/SysFunction.cpp
firebird/trunk/src/jrd/blb.cpp
firebird/trunk/src/jrd/constants.h
firebird/trunk/src/msgs/messages2.sql
firebird/trunk/src/msgs/system_errors2.sql
firebird/trunk/src/yvalve/gds.cpp
Modified: firebird/trunk/lang_helpers/gds_codes.ftn
===================================================================
--- firebird/trunk/lang_helpers/gds_codes.ftn 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/lang_helpers/gds_codes.ftn 2015-07-27 01:06:51 UTC (rev 62047)
@@ -2334,8 +2334,10 @@
PARAMETER (GDS__dsql_wlock_conflict = 336397329)
INTEGER*4 GDS__dsql_max_exception_arguments
PARAMETER (GDS__dsql_max_exception_arguments = 336397330)
- INTEGER*4 GDS__dsql_string_length
- PARAMETER (GDS__dsql_string_length = 336397331)
+ INTEGER*4 GDS__dsql_string_byte_length
+ PARAMETER (GDS__dsql_string_byte_length = 336397331)
+ INTEGER*4 GDS__dsql_string_char_length
+ PARAMETER (GDS__dsql_string_char_length = 336397332)
INTEGER*4 GDS__gsec_cant_open_db
PARAMETER (GDS__gsec_cant_open_db = 336723983)
INTEGER*4 GDS__gsec_switches_error
Modified: firebird/trunk/lang_helpers/gds_codes.pas
===================================================================
--- firebird/trunk/lang_helpers/gds_codes.pas 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/lang_helpers/gds_codes.pas 2015-07-27 01:06:51 UTC (rev 62047)
@@ -1174,7 +1174,8 @@
gds_dsql_wlock_aggregates = 336397328;
gds_dsql_wlock_conflict = 336397329;
gds_dsql_max_exception_arguments = 336397330;
- gds_dsql_string_length = 336397331;
+ gds_dsql_string_byte_length = 336397331;
+ gds_dsql_string_char_length = 336397332;
gds_gsec_cant_open_db = 336723983;
gds_gsec_switches_error = 336723984;
gds_gsec_no_op_spec = 336723985;
Modified: firebird/trunk/src/dsql/ExprNodes.cpp
===================================================================
--- firebird/trunk/src/dsql/ExprNodes.cpp 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/dsql/ExprNodes.cpp 2015-07-27 01:06:51 UTC (rev 62047)
@@ -3158,7 +3158,7 @@
if (value1->dsc_dtype == dtype_dbkey && value2->dsc_dtype == dtype_dbkey)
{
- if ((ULONG) value1->dsc_length + (ULONG) value2->dsc_length > MAX_COLUMN_SIZE - sizeof(USHORT))
+ if ((ULONG) value1->dsc_length + (ULONG) value2->dsc_length > MAX_STR_SIZE)
{
ERR_post(Arg::Gds(isc_concat_overflow));
return NULL;
@@ -3210,7 +3210,7 @@
{
fb_assert(desc.dsc_dtype == dtype_varying);
- if ((ULONG) length1 + (ULONG) length2 > MAX_COLUMN_SIZE - sizeof(USHORT))
+ if ((ULONG) length1 + (ULONG) length2 > MAX_STR_SIZE)
{
ERR_post(Arg::Gds(isc_concat_overflow));
return NULL;
@@ -6483,9 +6483,19 @@
}
else
{
- constant->litDesc.dsc_length =
- charSet->length(dsqlStr->getString().length(), constant->litDesc.dsc_address, true) *
- charSet->maxBytesPerChar();
+ ULONG charLength = charSet->length(
+ dsqlStr->getString().length(), constant->litDesc.dsc_address, true);
+
+ if (charLength > MAX_STR_SIZE / charSet->maxBytesPerChar())
+ {
+ ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
+ Arg::Gds(isc_dsql_string_char_length) <<
+ Arg::Num(charLength) <<
+ Arg::Num(MAX_STR_SIZE / charSet->maxBytesPerChar()) <<
+ METD_get_charset_name(dsqlScratch->getTransaction(), constant->litDesc.getCharSet()));
+ }
+ else
+ constant->litDesc.dsc_length = charLength * charSet->maxBytesPerChar();
}
constant->litDesc.dsc_length += adjust;
@@ -9769,8 +9779,8 @@
ULONG start = (ULONG) sStart;
ULONG length = (ULONG) sLength;
- if (desc.isText() && length > MAX_COLUMN_SIZE)
- length = MAX_COLUMN_SIZE;
+ if (desc.isText() && length > MAX_STR_SIZE)
+ length = MAX_STR_SIZE;
ULONG dataLen;
@@ -9888,7 +9898,7 @@
CharSet* charSet = INTL_charset_lookup(tdbb, desc.getCharSet());
desc.dsc_address = NULL;
- const ULONG totLen = MIN(MAX_COLUMN_SIZE, length * charSet->maxBytesPerChar());
+ const ULONG totLen = MIN(MAX_STR_SIZE, length * charSet->maxBytesPerChar());
desc.dsc_length = totLen;
EVL_make_value(tdbb, &desc, impure);
Modified: firebird/trunk/src/dsql/Parser.cpp
===================================================================
--- firebird/trunk/src/dsql/Parser.cpp 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/dsql/Parser.cpp 2015-07-27 01:06:51 UTC (rev 62047)
@@ -484,15 +484,15 @@
*p = *lex.ptr++;
}
- if (p - buffer > MAX_COLUMN_SIZE)
+ if (p - buffer > MAX_STR_SIZE)
{
if (buffer != string)
gds__free (buffer);
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
- Arg::Gds(isc_dsql_string_length) <<
+ Arg::Gds(isc_dsql_string_byte_length) <<
Arg::Num(p - buffer) <<
- Arg::Num(MAX_COLUMN_SIZE));
+ Arg::Num(MAX_STR_SIZE));
}
if (c == '"')
@@ -666,12 +666,12 @@
byte = c;
}
- if (temp.length() > MAX_COLUMN_SIZE)
+ if (temp.length() / 2 > MAX_STR_SIZE)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
- Arg::Gds(isc_dsql_string_length) <<
- Arg::Num(temp.length()) <<
- Arg::Num(MAX_COLUMN_SIZE));
+ Arg::Gds(isc_dsql_string_byte_length) <<
+ Arg::Num(temp.length() / 2) <<
+ Arg::Num(MAX_STR_SIZE));
}
yylval.intlStringPtr = newIntlString(temp, "BINARY");
@@ -715,12 +715,12 @@
{
size_t len = lex.ptr - lex.last_token - 4;
- if (len > MAX_COLUMN_SIZE)
+ if (len > MAX_STR_SIZE)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
- Arg::Gds(isc_dsql_string_length) <<
+ Arg::Gds(isc_dsql_string_byte_length) <<
Arg::Num(len) <<
- Arg::Num(MAX_COLUMN_SIZE));
+ Arg::Num(MAX_STR_SIZE));
}
yylval.intlStringPtr = newIntlString(Firebird::string(lex.last_token + 3, len));
Modified: firebird/trunk/src/dsql/gen.cpp
===================================================================
--- firebird/trunk/src/dsql/gen.cpp 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/dsql/gen.cpp 2015-07-27 01:06:51 UTC (rev 62047)
@@ -40,6 +40,7 @@
#include "../dsql/DdlNodes.h"
#include "../dsql/ExprNodes.h"
#include "../dsql/StmtNodes.h"
+#include "../dsql/DSqlDataTypeUtil.h"
#include "../jrd/RecordSourceNodes.h"
#include "../jrd/ibase.h"
#include "../jrd/align.h"
@@ -158,6 +159,7 @@
dsqlScratch->appendUChar(message->msg_number);
dsqlScratch->appendUShort(message->msg_parameter);
+ DSqlDataTypeUtil dataTypeUtil(dsqlScratch);
ULONG offset = 0;
for (FB_SIZE_T i = 0; i < message->msg_parameters.getCount(); ++i)
@@ -207,7 +209,8 @@
// But we flag it to describe as text.
parameter->par_is_text = true;
parameter->par_desc.dsc_dtype = dtype_varying;
- parameter->par_desc.dsc_length += sizeof(USHORT);
+ parameter->par_desc.dsc_length = dataTypeUtil.fixLength(
+ ¶meter->par_desc, parameter->par_desc.dsc_length) + sizeof(USHORT);
}
const USHORT align = type_alignments[parameter->par_desc.dsc_dtype];
Modified: firebird/trunk/src/include/gen/codetext.h
===================================================================
--- firebird/trunk/src/include/gen/codetext.h 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/include/gen/codetext.h 2015-07-27 01:06:51 UTC (rev 62047)
@@ -1163,7 +1163,8 @@
{"dsql_wlock_aggregates", 336397328},
{"dsql_wlock_conflict", 336397329},
{"dsql_max_exception_arguments", 336397330},
- {"dsql_string_length", 336397331},
+ {"dsql_string_byte_length", 336397331},
+ {"dsql_string_char_length", 336397332},
{"gsec_cant_open_db", 336723983},
{"gsec_switches_error", 336723984},
{"gsec_no_op_spec", 336723985},
Modified: firebird/trunk/src/include/gen/iberror.h
===================================================================
--- firebird/trunk/src/include/gen/iberror.h 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/include/gen/iberror.h 2015-07-27 01:06:51 UTC (rev 62047)
@@ -1197,7 +1197,8 @@
const ISC_STATUS isc_dsql_wlock_aggregates = 336397328L;
const ISC_STATUS isc_dsql_wlock_conflict = 336397329L;
const ISC_STATUS isc_dsql_max_exception_arguments = 336397330L;
-const ISC_STATUS isc_dsql_string_length = 336397331L;
+const ISC_STATUS isc_dsql_string_byte_length = 336397331L;
+const ISC_STATUS isc_dsql_string_char_length = 336397332L;
const ISC_STATUS isc_gsec_cant_open_db = 336723983L;
const ISC_STATUS isc_gsec_switches_error = 336723984L;
const ISC_STATUS isc_gsec_no_op_spec = 336723985L;
@@ -1300,7 +1301,7 @@
const ISC_STATUS isc_trace_switch_param_miss = 337182758L;
const ISC_STATUS isc_trace_param_act_notcompat = 337182759L;
const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L;
-const ISC_STATUS isc_err_max = 1244;
+const ISC_STATUS isc_err_max = 1245;
#else /* c definitions */
@@ -2467,7 +2468,8 @@
#define isc_dsql_wlock_aggregates 336397328L
#define isc_dsql_wlock_conflict 336397329L
#define isc_dsql_max_exception_arguments 336397330L
-#define isc_dsql_string_length 336397331L
+#define isc_dsql_string_byte_length 336397331L
+#define isc_dsql_string_char_length 336397332L
#define isc_gsec_cant_open_db 336723983L
#define isc_gsec_switches_error 336723984L
#define isc_gsec_no_op_spec 336723985L
@@ -2570,7 +2572,7 @@
#define isc_trace_switch_param_miss 337182758L
#define isc_trace_param_act_notcompat 337182759L
#define isc_trace_mandatory_switch_miss 337182760L
-#define isc_err_max 1244
+#define isc_err_max 1245
#endif
Modified: firebird/trunk/src/include/gen/msgs.h
===================================================================
--- firebird/trunk/src/include/gen/msgs.h 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/include/gen/msgs.h 2015-07-27 01:06:51 UTC (rev 62047)
@@ -1166,7 +1166,8 @@
{336397328, "WITH LOCK cannot be used with aggregates"}, /* dsql_wlock_aggregates */
{336397329, "WITH LOCK cannot be used with @1"}, /* dsql_wlock_conflict */
{336397330, "Number of arguments (@1) exceeds the maximum (@2) number of EXCEPTION USING arguments"}, /* dsql_max_exception_arguments */
- {336397331, "String literal with @1 bytes exceeds the maximum length of @2 bytes"}, /* dsql_string_length */
+ {336397331, "String literal with @1 bytes exceeds the maximum length of @2 bytes"}, /* dsql_string_byte_length */
+ {336397332, "String literal with @1 characters exceeds the maximum length of @2 characters for the @3 character set"}, /* dsql_string_char_length */
{336723983, "unable to open database"}, /* gsec_cant_open_db */
{336723984, "error in switch specifications"}, /* gsec_switches_error */
{336723985, "no operation specified"}, /* gsec_no_op_spec */
Modified: firebird/trunk/src/include/gen/sql_code.h
===================================================================
--- firebird/trunk/src/include/gen/sql_code.h 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/include/gen/sql_code.h 2015-07-27 01:06:51 UTC (rev 62047)
@@ -1162,7 +1162,8 @@
{336397328, -104}, /* 1040 dsql_wlock_aggregates */
{336397329, -104}, /* 1041 dsql_wlock_conflict */
{336397330, -901}, /* 1042 dsql_max_exception_arguments */
- {336397331, -901}, /* 1043 dsql_string_length */
+ {336397331, -901}, /* 1043 dsql_string_byte_length */
+ {336397332, -901}, /* 1044 dsql_string_char_length */
{336723983, -901}, /* 15 gsec_cant_open_db */
{336723984, -901}, /* 16 gsec_switches_error */
{336723985, -901}, /* 17 gsec_no_op_spec */
Modified: firebird/trunk/src/include/gen/sql_state.h
===================================================================
--- firebird/trunk/src/include/gen/sql_state.h 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/include/gen/sql_state.h 2015-07-27 01:06:51 UTC (rev 62047)
@@ -1162,7 +1162,8 @@
{336397328, "42000"}, // 1040 dsql_wlock_aggregates
{336397329, "42000"}, // 1041 dsql_wlock_conflict
{336397330, "07002"}, // 1042 dsql_max_exception_arguments
- {336397331, "42000"}, // 1043 dsql_string_length
+ {336397331, "42000"}, // 1043 dsql_string_byte_length
+ {336397332, "42000"}, // 1044 dsql_string_char_length
{336723983, "00000"}, // 15 gsec_cant_open_db
{336723984, "00000"}, // 16 gsec_switches_error
{336723985, "00000"}, // 17 gsec_no_op_spec
Modified: firebird/trunk/src/jrd/DataTypeUtil.cpp
===================================================================
--- firebird/trunk/src/jrd/DataTypeUtil.cpp 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/jrd/DataTypeUtil.cpp 2015-07-27 01:06:51 UTC (rev 62047)
@@ -234,7 +234,7 @@
else if (desc->dsc_dtype == dtype_cstring)
overhead = sizeof(UCHAR);
- return MIN(((MAX_COLUMN_SIZE - overhead) / bpc) * bpc, length);
+ return MIN(((MAX_STR_SIZE - overhead) / bpc) * bpc, length);
}
@@ -308,7 +308,7 @@
{
SLONG constant = CVT_get_long(length, 0, ERR_post);
fb_assert(constant >= 0);
- len = MIN(len, MIN(MAX_COLUMN_SIZE, ULONG(constant)) * maxBytesPerChar(result->getCharSet()));
+ len = MIN(len, MIN(MAX_STR_SIZE, ULONG(constant)) * maxBytesPerChar(result->getCharSet()));
}
result->dsc_length = fixLength(result, len) + static_cast<USHORT>(sizeof(USHORT));
Modified: firebird/trunk/src/jrd/SysFunction.cpp
===================================================================
--- firebird/trunk/src/jrd/SysFunction.cpp 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/jrd/SysFunction.cpp 2015-07-27 01:06:51 UTC (rev 62047)
@@ -528,7 +528,7 @@
makeFromListResult(dataTypeUtil, function, result, argsCount, args);
if (result->isText())
- result->makeVarying(dataTypeUtil->fixLength(result, MAX_COLUMN_SIZE), result->getTextType());
+ result->makeVarying(dataTypeUtil->fixLength(result, MAX_STR_SIZE), result->getTextType());
}
***/
@@ -892,7 +892,7 @@
else
{
result->dsc_length = static_cast<USHORT>(sizeof(USHORT)) +
- dataTypeUtil->fixLength(result, MAX_COLUMN_SIZE);
+ dataTypeUtil->fixLength(result, MAX_STR_SIZE);
}
}
@@ -2768,7 +2768,7 @@
if (!value->isBlob() && !placing->isBlob())
{
const SINT64 newlen = (SINT64) len1 - length + len2;
- if (newlen > static_cast<SINT64>(MAX_COLUMN_SIZE - sizeof(USHORT)))
+ if (newlen > static_cast<SINT64>(MAX_STR_SIZE))
status_exception::raise(Arg::Gds(isc_arith_except) << Arg::Gds(isc_imp_exc));
dsc desc;
@@ -2910,7 +2910,7 @@
}
else
{
- if (padLen * cs->maxBytesPerChar() > MAX_COLUMN_SIZE - sizeof(USHORT))
+ if (padLen * cs->maxBytesPerChar() > MAX_STR_SIZE)
status_exception::raise(Arg::Gds(isc_arith_except) << Arg::Gds(isc_imp_exc));
dsc desc;
@@ -3266,7 +3266,7 @@
const unsigned int findLen = canonicals[1].getCount() / canonicalWidth;
const unsigned int replacementLen = lengths[2] / cs->minBytesPerChar();
- const USHORT len = MIN(MAX_COLUMN_SIZE, cs->maxBytesPerChar() *
+ const USHORT len = MIN(MAX_STR_SIZE, cs->maxBytesPerChar() *
MAX(searchedLen, searchedLen + (searchedLen / findLen) * (replacementLen - findLen)));
dsc desc;
Modified: firebird/trunk/src/jrd/blb.cpp
===================================================================
--- firebird/trunk/src/jrd/blb.cpp 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/jrd/blb.cpp 2015-07-27 01:06:51 UTC (rev 62047)
@@ -2648,7 +2648,7 @@
buffer.getBuffer((blob->blb_length / fromCharSet->minBytesPerChar()) * toCharSet->maxBytesPerChar());
const ULONG len = blob->BLB_get_data(tdbb, buffer.begin(), buffer.getCapacity(), true);
- if (len > MAX_COLUMN_SIZE - sizeof(USHORT))
+ if (len > MAX_STR_SIZE)
ERR_post(Arg::Gds(isc_arith_except) << Arg::Gds(isc_blob_truncation));
blobAsText.dsc_address = buffer.begin();
Modified: firebird/trunk/src/jrd/constants.h
===================================================================
--- firebird/trunk/src/jrd/constants.h 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/jrd/constants.h 2015-07-27 01:06:51 UTC (rev 62047)
@@ -52,7 +52,8 @@
// Column Limits
-const ULONG MAX_COLUMN_SIZE = 32767; // Bytes
+const ULONG MAX_COLUMN_SIZE = 32767; // Bytes
+const ULONG MAX_STR_SIZE = 65535; // Bytes
// Metadata constants
Modified: firebird/trunk/src/msgs/messages2.sql
===================================================================
--- firebird/trunk/src/msgs/messages2.sql 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/msgs/messages2.sql 2015-07-27 01:06:51 UTC (rev 62047)
@@ -2628,7 +2628,8 @@
('dsql_wlock_aggregates', 'pass1_rse_impl', 'pass1.cpp', NULL, 13, 1040, NULL, 'WITH LOCK cannot be used with aggregates', NULL, NULL);
('dsql_wlock_conflict', NULL, 'pass1.cpp', NULL, 13, 1041, NULL, 'WITH LOCK cannot be used with @1', NULL, NULL);
('dsql_max_exception_arguments', NULL, 'StmtNodes.cpp', NULL, 13, 1042, NULL, 'Number of arguments (@1) exceeds the maximum (@2) number of EXCEPTION USING arguments', NULL, NULL);
-('dsql_string_length', NULL, 'Parser.cpp', NULL, 13, 1043, NULL, 'String literal with @1 bytes exceeds the maximum length of @2 bytes', NULL, NULL);
+('dsql_string_byte_length', NULL, 'Parser.cpp', NULL, 13, 1043, NULL, 'String literal with @1 bytes exceeds the maximum length of @2 bytes', NULL, NULL);
+('dsql_string_char_length', NULL, 'Parser.cpp', NULL, 13, 1044, NULL, 'String literal with @1 characters exceeds the maximum length of @2 characters for the @3 character set', NULL, NULL);
-- SQLWARN
(NULL, NULL, NULL, NULL, 14, 100, NULL, 'Row not found for fetch, update or delete, or the result of a query is an empty table.', NULL, NULL);
(NULL, NULL, NULL, NULL, 14, 101, NULL, 'segment buffer length shorter than expected', NULL, NULL);
Modified: firebird/trunk/src/msgs/system_errors2.sql
===================================================================
--- firebird/trunk/src/msgs/system_errors2.sql 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/msgs/system_errors2.sql 2015-07-27 01:06:51 UTC (rev 62047)
@@ -1156,7 +1156,8 @@
(-104, '42', '000', 13, 1040, 'dsql_wlock_aggregates', NULL, NULL)
(-104, '42', '000', 13, 1041, 'dsql_wlock_conflict', NULL, NULL)
(-901, '07', '002', 13, 1042, 'dsql_max_exception_arguments', NULL, NULL)
-(-901, '42', '000', 13, 1043, 'dsql_string_length', NULL, NULL)
+(-901, '42', '000', 13, 1043, 'dsql_string_byte_length', NULL, NULL)
+(-901, '42', '000', 13, 1044, 'dsql_string_char_length', NULL, NULL)
-- GSEC
(-901, '00', '000', 18, 15, 'gsec_cant_open_db', NULL, NULL)
(-901, '00', '000', 18, 16, 'gsec_switches_error', NULL, NULL)
Modified: firebird/trunk/src/yvalve/gds.cpp
===================================================================
--- firebird/trunk/src/yvalve/gds.cpp 2015-07-27 01:06:33 UTC (rev 62046)
+++ firebird/trunk/src/yvalve/gds.cpp 2015-07-27 01:06:51 UTC (rev 62047)
@@ -3249,9 +3249,15 @@
break;
case op_literal:
- while (--n >= 0)
+ {
+ USHORT un = (USHORT) n;
+
+ while (un-- > 0)
blr_print_char(control);
+
+ n = (SSHORT) un;
break;
+ }
case op_join:
blr_print_join(control);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|