summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authorunknown <acurtis@ltantony.rdg.cyberkinetica.homeunix.net>2005-03-08 22:32:09 +0000
committerunknown <acurtis@ltantony.rdg.cyberkinetica.homeunix.net>2005-03-08 22:32:09 +0000
commitce16c895c243107b66507242539544d5bbec8841 (patch)
treea0cecfd9009503e0a1a4a4e424a679143292ab71 /sql/sql_table.cc
parentfe3a425a94dd321844fab1867811016b9e5343c7 (diff)
parent1220069c537a733b233c446e27aec9f9247aef31 (diff)
downloadmariadb-git-ce16c895c243107b66507242539544d5bbec8841.tar.gz
Merge in fix Bug#3788
mysql-test/r/information_schema.result: Auto merged mysql-test/t/sp.test: Auto merged sql/item.cc: Auto merged sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/mysql_priv.h: Auto merged sql/sp.cc: Auto merged sql/sp_head.cc: Auto merged sql/sp_head.h: Auto merged sql/sql_parse.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_yacc.yy: Auto merged mysql-test/r/sp.result: Merge BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc314
1 files changed, 179 insertions, 135 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 7ab1a0a3777..31a1f51b085 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -432,6 +432,173 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
/*
+ Prepare a create_table instance for packing
+
+ SYNOPSIS
+ prepare_create_field()
+ sql_field field to prepare for packing
+ blob_columns count for BLOBs
+ timestamps count for timestamps
+ table_flags table flags
+
+ DESCRIPTION
+ This function prepares a create_field instance.
+ Fields such as pack_flag are valid after this call.
+
+ RETURN VALUES
+ 0 ok
+ 1 Error
+*/
+
+int prepare_create_field(create_field *sql_field,
+ uint &blob_columns,
+ int &timestamps, int &timestamps_with_niladic,
+ uint table_flags)
+{
+ DBUG_ENTER("prepare_field");
+ {
+ /* This code came from mysql_prepare_table.
+ Indent preserved to make patching easier */
+ DBUG_ASSERT(sql_field->charset);
+
+ switch (sql_field->sql_type) {
+ case FIELD_TYPE_BLOB:
+ case FIELD_TYPE_MEDIUM_BLOB:
+ case FIELD_TYPE_TINY_BLOB:
+ case FIELD_TYPE_LONG_BLOB:
+ sql_field->pack_flag=FIELDFLAG_BLOB |
+ pack_length_to_packflag(sql_field->pack_length -
+ portable_sizeof_char_ptr);
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->length=8; // Unireg field length
+ sql_field->unireg_check=Field::BLOB_FIELD;
+ blob_columns++;
+ break;
+ case FIELD_TYPE_GEOMETRY:
+#ifdef HAVE_SPATIAL
+ if (!(table_flags & HA_CAN_GEOMETRY))
+ {
+ my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
+ MYF(0), "GEOMETRY");
+ DBUG_RETURN(1);
+ }
+ sql_field->pack_flag=FIELDFLAG_GEOM |
+ pack_length_to_packflag(sql_field->pack_length -
+ portable_sizeof_char_ptr);
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->length=8; // Unireg field length
+ sql_field->unireg_check=Field::BLOB_FIELD;
+ blob_columns++;
+ break;
+#else
+ my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
+ sym_group_geom.name, sym_group_geom.needed_define);
+ DBUG_RETURN(1);
+#endif /*HAVE_SPATIAL*/
+ case MYSQL_TYPE_VARCHAR:
+#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
+ if (table_flags & HA_NO_VARCHAR)
+ {
+ /* convert VARCHAR to CHAR because handler is not yet up to date */
+ sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
+ sql_field->pack_length= calc_pack_length(sql_field->sql_type,
+ (uint) sql_field->length);
+ if ((sql_field->length / sql_field->charset->mbmaxlen) >
+ MAX_FIELD_CHARLENGTH)
+ {
+ my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
+ MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
+ DBUG_RETURN(1);
+ }
+ }
+#endif
+ /* fall through */
+ case FIELD_TYPE_STRING:
+ sql_field->pack_flag=0;
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ break;
+ case FIELD_TYPE_ENUM:
+ sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
+ FIELDFLAG_INTERVAL;
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->unireg_check=Field::INTERVAL_FIELD;
+ check_duplicates_in_interval("ENUM",sql_field->field_name,
+ sql_field->interval,
+ sql_field->charset);
+ break;
+ case FIELD_TYPE_SET:
+ sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
+ FIELDFLAG_BITFIELD;
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->unireg_check=Field::BIT_FIELD;
+ check_duplicates_in_interval("SET",sql_field->field_name,
+ sql_field->interval,
+ sql_field->charset);
+ break;
+ case FIELD_TYPE_DATE: // Rest of string types
+ case FIELD_TYPE_NEWDATE:
+ case FIELD_TYPE_TIME:
+ case FIELD_TYPE_DATETIME:
+ case FIELD_TYPE_NULL:
+ sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
+ break;
+ case FIELD_TYPE_BIT:
+ if (!(table_flags & HA_CAN_BIT_FIELD))
+ {
+ my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "BIT FIELD");
+ DBUG_RETURN(1);
+ }
+ sql_field->pack_flag= FIELDFLAG_NUMBER;
+ break;
+ case FIELD_TYPE_NEWDECIMAL:
+ sql_field->pack_flag=(FIELDFLAG_NUMBER |
+ (sql_field->flags & UNSIGNED_FLAG ? 0 :
+ FIELDFLAG_DECIMAL) |
+ (sql_field->flags & ZEROFILL_FLAG ?
+ FIELDFLAG_ZEROFILL : 0) |
+ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
+ break;
+ case FIELD_TYPE_TIMESTAMP:
+ /* We should replace old TIMESTAMP fields with their newer analogs */
+ if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
+ {
+ if (!timestamps)
+ {
+ sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
+ timestamps_with_niladic++;
+ }
+ else
+ sql_field->unireg_check= Field::NONE;
+ }
+ else if (sql_field->unireg_check != Field::NONE)
+ timestamps_with_niladic++;
+
+ timestamps++;
+ /* fall-through */
+ default:
+ sql_field->pack_flag=(FIELDFLAG_NUMBER |
+ (sql_field->flags & UNSIGNED_FLAG ? 0 :
+ FIELDFLAG_DECIMAL) |
+ (sql_field->flags & ZEROFILL_FLAG ?
+ FIELDFLAG_ZEROFILL : 0) |
+ f_settype((uint) sql_field->sql_type) |
+ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
+ break;
+ }
+ if (!(sql_field->flags & NOT_NULL_FLAG))
+ sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
+ if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
+ sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
+ }
+ DBUG_RETURN(0);
+}
+
+/*
Preparation for table creation
SYNOPSIS
@@ -690,142 +857,17 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
DBUG_ASSERT(sql_field->charset != 0);
- switch (sql_field->sql_type) {
- case FIELD_TYPE_BLOB:
- case FIELD_TYPE_MEDIUM_BLOB:
- case FIELD_TYPE_TINY_BLOB:
- case FIELD_TYPE_LONG_BLOB:
- sql_field->pack_flag=FIELDFLAG_BLOB |
- pack_length_to_packflag(sql_field->pack_length -
- portable_sizeof_char_ptr);
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->length=8; // Unireg field length
- sql_field->unireg_check=Field::BLOB_FIELD;
- blob_columns++;
- create_info->varchar= 1;
- break;
- case FIELD_TYPE_GEOMETRY:
-#ifdef HAVE_SPATIAL
- if (!(file->table_flags() & HA_CAN_GEOMETRY))
- {
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "GEOMETRY");
- DBUG_RETURN(-1);
- }
- sql_field->pack_flag=FIELDFLAG_GEOM |
- pack_length_to_packflag(sql_field->pack_length -
- portable_sizeof_char_ptr);
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->length=8; // Unireg field length
- sql_field->unireg_check=Field::BLOB_FIELD;
- blob_columns++;
- create_info->varchar= 1;
- break;
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
+ if (prepare_create_field(sql_field, blob_columns,
+ timestamps, timestamps_with_niladic,
+ file->table_flags()))
DBUG_RETURN(-1);
-#endif /*HAVE_SPATIAL*/
- case MYSQL_TYPE_VARCHAR:
-#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
- if (file->table_flags() & HA_NO_VARCHAR)
- {
- /* convert VARCHAR to CHAR because handler is not yet up to date */
- sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
- sql_field->pack_length= calc_pack_length(sql_field->sql_type,
- (uint) sql_field->length);
- if ((sql_field->length / sql_field->charset->mbmaxlen) >
- MAX_FIELD_CHARLENGTH)
- {
- my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
- MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
- DBUG_RETURN(-1);
- }
- }
- else
-#endif
- create_info->varchar= 1;
- /* fall through */
- case MYSQL_TYPE_STRING:
- sql_field->pack_flag=0;
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|= FIELDFLAG_BINARY;
- break;
- case FIELD_TYPE_ENUM:
- sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
- FIELDFLAG_INTERVAL;
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->unireg_check=Field::INTERVAL_FIELD;
- check_duplicates_in_interval("ENUM",sql_field->field_name,
- sql_field->interval,
- sql_field->charset);
- break;
- case FIELD_TYPE_SET:
- sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
- FIELDFLAG_BITFIELD;
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->unireg_check=Field::BIT_FIELD;
- check_duplicates_in_interval("SET",sql_field->field_name,
- sql_field->interval,
- sql_field->charset);
- break;
- case FIELD_TYPE_DATE: // Rest of string types
- case FIELD_TYPE_NEWDATE:
- case FIELD_TYPE_TIME:
- case FIELD_TYPE_DATETIME:
- case FIELD_TYPE_NULL:
- sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
- break;
- case FIELD_TYPE_BIT:
- if (!(file->table_flags() & HA_CAN_BIT_FIELD))
- {
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "BIT FIELD");
- DBUG_RETURN(-1);
- }
- sql_field->pack_flag= FIELDFLAG_NUMBER;
- break;
- case FIELD_TYPE_NEWDECIMAL:
- sql_field->pack_flag=(FIELDFLAG_NUMBER |
- (sql_field->flags & UNSIGNED_FLAG ? 0 :
- FIELDFLAG_DECIMAL) |
- (sql_field->flags & ZEROFILL_FLAG ?
- FIELDFLAG_ZEROFILL : 0) |
- (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
- break;
- case FIELD_TYPE_TIMESTAMP:
- /* We should replace old TIMESTAMP fields with their newer analogs */
- if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
- {
- if (!timestamps)
- {
- sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
- timestamps_with_niladic++;
- }
- else
- sql_field->unireg_check= Field::NONE;
- }
- else if (sql_field->unireg_check != Field::NONE)
- timestamps_with_niladic++;
-
- timestamps++;
- /* fall-through */
- default:
- sql_field->pack_flag=(FIELDFLAG_NUMBER |
- (sql_field->flags & UNSIGNED_FLAG ? 0 :
- FIELDFLAG_DECIMAL) |
- (sql_field->flags & ZEROFILL_FLAG ?
- FIELDFLAG_ZEROFILL : 0) |
- f_settype((uint) sql_field->sql_type) |
- (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
- break;
- }
- if (!(sql_field->flags & NOT_NULL_FLAG))
- sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
- if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
- sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
+ if (sql_field->sql_type == FIELD_TYPE_BLOB ||
+ sql_field->sql_type == FIELD_TYPE_MEDIUM_BLOB ||
+ sql_field->sql_type == FIELD_TYPE_TINY_BLOB ||
+ sql_field->sql_type == FIELD_TYPE_LONG_BLOB ||
+ sql_field->sql_type == FIELD_TYPE_GEOMETRY ||
+ sql_field->sql_type == MYSQL_TYPE_VARCHAR)
+ create_info->varchar= 1;
sql_field->offset= pos;
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
auto_increment++;
@@ -1592,6 +1634,8 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
((Item_field *)item)->field :
(Field*) 0))))
DBUG_RETURN(0);
+ if (item->maybe_null)
+ cr_field->flags &= ~NOT_NULL_FLAG;
extra_fields->push_back(cr_field);
}
/*