aboutsummaryrefslogtreecommitdiff
path: root/odb
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-01-22 17:43:56 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-01-22 17:43:56 +0200
commit94d00afa2896a0a418da029aee1e5354c49759dd (patch)
tree42f2f82c33b6930e6153f0bdbb5cea4cda5ad073 /odb
parent43539f96afd937bb8a5b73c98a755a9de93c5f49 (diff)
Pass precision and scale to Oracle query_param
Diffstat (limited to 'odb')
-rw-r--r--odb/relational/oracle/common.cxx84
-rw-r--r--odb/relational/oracle/context.cxx16
-rw-r--r--odb/relational/oracle/header.cxx23
3 files changed, 105 insertions, 18 deletions
diff --git a/odb/relational/oracle/common.cxx b/odb/relational/oracle/common.cxx
index 708c4e7..3b1c1b6 100644
--- a/odb/relational/oracle/common.cxx
+++ b/odb/relational/oracle/common.cxx
@@ -215,7 +215,6 @@ namespace relational
{
traverse_interval_ym (mi);
break;
-
}
case sql_type::INTERVAL_DS:
{
@@ -479,6 +478,89 @@ namespace relational
{
query_columns (base const& x): base (x) {}
+ virtual void
+ column_ctor (string const& type, string const& base)
+ {
+ os << type << " (const char* t," << endl
+ << "const char* c," << endl
+ << "unsigned short p = 0xFFF," << endl
+ << "short s = 0xFFF)" << endl
+ << " : " << base << " (t, c, p, s)"
+ << "{"
+ << "}";
+ }
+
+ virtual void
+ column_ctor_extra (semantics::data_member& m)
+ {
+ // For some types we need to pass precision and scale.
+ //
+ sql_type const& st (column_sql_type (m));
+
+ switch (st.type)
+ {
+ case sql_type::NUMBER:
+ {
+ if (st.prec)
+ {
+ os << ", " << st.prec_value;
+
+ if (st.scale)
+ os << ", " << st.scale_value;
+ }
+ break;
+ }
+ case sql_type::FLOAT:
+ {
+ os << ", " << st.prec_value;
+ break;
+ }
+ case sql_type::TIMESTAMP:
+ {
+ os << ", " << st.prec_value;
+ break;
+ }
+ case sql_type::INTERVAL_YM:
+ {
+ os << ", " << st.prec_value;
+ break;
+ }
+ case sql_type::INTERVAL_DS:
+ {
+ // INTERVAL DAY TO SECOND has two precisions.
+ //
+ os << ", " << st.prec_value << ", " << st.scale_value;
+ break;
+ }
+ case sql_type::CHAR:
+ case sql_type::NCHAR:
+ case sql_type::VARCHAR2:
+ case sql_type::NVARCHAR2:
+ case sql_type::RAW:
+ {
+ // The same logic as in header.cxx.
+ //
+ size_t n (st.prec ? st.prec_value : 1);
+
+ if (!st.byte_semantics)
+ n *= 4;
+
+ if (st.type == sql_type::VARCHAR2 ||
+ st.type == sql_type::NVARCHAR2)
+ n = n > 4000 ? 4000 : n;
+ else
+ n = n > 2000 ? 2000 : n;
+
+ os << ", " << n;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
virtual string
database_type_id (semantics::data_member& m)
{
diff --git a/odb/relational/oracle/context.cxx b/odb/relational/oracle/context.cxx
index 0f9bae1..d477a19 100644
--- a/odb/relational/oracle/context.cxx
+++ b/odb/relational/oracle/context.cxx
@@ -400,11 +400,13 @@ namespace relational
// However, this may change in future versions.
//
r.type = sql_type::VARCHAR2;
+ r.byte_semantics = true;
s = parse_prec;
}
else if (id == "NVARCHAR2")
{
r.type = sql_type::NVARCHAR2;
+ r.byte_semantics = false;
s = parse_prec;
}
else if (id == "VARYING")
@@ -412,11 +414,17 @@ namespace relational
// VARYING always appears at the end of an identifier.
//
if (prefix == "CHAR" || prefix == "CHARACTER")
+ {
r.type = sql_type::VARCHAR2;
+ r.byte_semantics = true;
+ }
else if (prefix == "NCHAR" ||
prefix == "NATIONAL CHAR" ||
prefix == "NATIONAL CHARACTER")
+ {
r.type = sql_type::NVARCHAR2;
+ r.byte_semantics = false;
+ }
s = parse_prec;
}
@@ -473,18 +481,18 @@ namespace relational
if (prefix == "CHAR" || prefix == "CHARACTER")
{
r.type = sql_type::CHAR;
+ r.byte_semantics = true;
r.prec = true;
r.prec_value = 1;
- r.byte_semantics = true;
}
else if (prefix == "NCHAR" ||
prefix == "NATIONAL CHAR" ||
prefix == "NATIONAL CHARACTER")
{
r.type = sql_type::NCHAR;
+ r.byte_semantics = false;
r.prec = true;
r.prec_value = 1;
- r.byte_semantics = false;
}
else if (prefix == "TIMESTAMP")
{
@@ -643,18 +651,18 @@ namespace relational
if (prefix == "CHAR" || prefix == "CHARACTER")
{
r.type = sql_type::CHAR;
+ r.byte_semantics = true;
r.prec = true;
r.prec_value = 1;
- r.byte_semantics = true;
}
else if (prefix == "NCHAR" ||
prefix == "NATIONAL CHAR" ||
prefix == "NATIONAL CHARACTER")
{
r.type = sql_type::NCHAR;
+ r.byte_semantics = false;
r.prec = true;
r.prec_value = 1;
- r.byte_semantics = false;
}
else if (prefix == "TIMESTAMP")
{
diff --git a/odb/relational/oracle/header.cxx b/odb/relational/oracle/header.cxx
index c302a82..8b9b93e 100644
--- a/odb/relational/oracle/header.cxx
+++ b/odb/relational/oracle/header.cxx
@@ -184,23 +184,20 @@ namespace relational
{
size_t n (mi.st->prec ? mi.st->prec_value : 1);
- // National characters can be either UTF-8 or UTF-16 encoded, both
- // of which have a maximum character encoding size of 4 bytes.
- // Assume the database character set uses a single byte fixed width
- // encoding.
+ // National characters can be either UTF-8 or UTF-16 encoded,
+ // both of which have a maximum character encoding size of 4
+ // bytes. Database character set can also be UTF-8 so if the
+ // size is specified in characters, then conservatively assume
+ // each character can take up to 4 bytes.
//
- sql_type::core_type t (mi.st->type);
-
- if ((t == sql_type::NCHAR || t == sql_type::NVARCHAR2) &&
- !mi.st->byte_semantics)
+ if (!mi.st->byte_semantics) // N*CHAR always has CHAR semantics.
n *= 4;
- if (t == sql_type::CHAR ||
- t == sql_type::NCHAR ||
- t == sql_type::RAW)
- n = n > 2000 ? 2000 : n;
- else if (t == sql_type::VARCHAR2 || t == sql_type::NVARCHAR2)
+ if (mi.st->type == sql_type::VARCHAR2 ||
+ mi.st->type == sql_type::NVARCHAR2)
n = n > 4000 ? 4000 : n;
+ else
+ n = n > 2000 ? 2000 : n;
os << "char " << mi.var << "value[" << n << "];"
<< "ub2 " << mi.var << "size;"