Fixed data truncation issue when updating the data of type character with length. Fixes #5481

This commit is contained in:
Akshay Joshi 2020-05-25 17:05:47 +05:30
parent 22c3a2649b
commit b1cbcc7ef6
6 changed files with 641 additions and 126 deletions

View File

@ -47,6 +47,7 @@ Bug fixes
| `Issue #5469 <https://redmine.postgresql.org/issues/5469>`_ - Fixed an issue where select2 hover is inconsistent for the SSL field in create server dialog.
| `Issue #5473 <https://redmine.postgresql.org/issues/5473>`_ - Fixed post-login redirect location when running in server mode under a non-default root.
| `Issue #5480 <https://redmine.postgresql.org/issues/5480>`_ - Fixed an issue where the background job creation fails if there is only a version-specific python binary available in PATH.
| `Issue #5481 <https://redmine.postgresql.org/issues/5481>`_ - Fixed data truncation issue when updating the data of type character with length.
| `Issue #5487 <https://redmine.postgresql.org/issues/5487>`_ - Fixed an issue where if LDAP_SEARCH_BASE_DN is not set then, the value for LDAP_BASE_DN will be considered.
| `Issue #5496 <https://redmine.postgresql.org/issues/5496>`_ - Fixed an issue where clicking on Select All button, not selecting all the options in pgAgent job scheduler.
| `Issue #5503 <https://redmine.postgresql.org/issues/5503>`_ - Clarify and correct the docs on enabling the pl/debugger plugin on the server.

View File

@ -4,7 +4,7 @@ INSERT INTO {{ conn|qtIdent(nsp_name, object_name) }} (
{% if not loop.first %}, {% endif %}{{ conn|qtIdent(col) }}{% endfor %}
) VALUES (
{% for col in data_to_be_saved %}
{% if not loop.first %}, {% endif %}%({{ pgadmin_alias[col] }})s::{{ data_type[col] }}{% endfor %}
{% if not loop.first %}, {% endif %}%({{ pgadmin_alias[col] }})s{% if type_cast_required[col] %}::{{ data_type[col] }}{% endif %}{% endfor %}
)
{% if pk_names and not has_oids %} returning {{pk_names}}{% endif %}
{% if has_oids %} returning oid{% endif %};

View File

@ -1,7 +1,7 @@
{# Update the row with primary keys (specified in primary_keys) #}
UPDATE {{ conn|qtIdent(nsp_name, object_name) }} SET
{% for col in data_to_be_saved %}
{% if not loop.first %}, {% endif %}{{ conn|qtIdent(col) }} = %({{ pgadmin_alias[col] }})s::{{ data_type[col] }}{% endfor %}
{% if not loop.first %}, {% endif %}{{ conn|qtIdent(col) }} = %({{ pgadmin_alias[col] }})s{% if type_cast_required[col] %}::{{ data_type[col] }}{% endif %}{% endfor %}
WHERE
{% for pk in primary_keys %}
{% if not loop.first %} AND {% endif %}{{ conn|qtIdent(pk) }} = {{ primary_keys[pk]|qtLiteral }}{% endfor %};

View File

@ -42,7 +42,8 @@ class TestViewDataTemplates(BaseTestGenerator):
nsp_name='test_schema',
data_type={'text': 'text', 'id': 'integer'},
pk_names='id',
has_oids=False
has_oids=False,
type_cast_required={'text': 'True', 'id': 'True'}
),
insert_expected_return_value='INSERT INTO'
' test_schema.test_table'
@ -73,7 +74,8 @@ class TestViewDataTemplates(BaseTestGenerator):
nsp_name='test_schema',
data_type={'text': 'text', 'id': 'integer'},
pk_names='id, text',
has_oids=False
has_oids=False,
type_cast_required={'text': 'True', 'id': 'True'}
),
insert_expected_return_value='INSERT INTO'
' test_schema.test_table'
@ -106,7 +108,8 @@ class TestViewDataTemplates(BaseTestGenerator):
nsp_name='test_schema',
data_type={'text': 'text', 'id': 'integer'},
pk_names='id',
has_oids=True
has_oids=True,
type_cast_required={'text': 'True', 'id': 'True'}
),
insert_expected_return_value='INSERT INTO'
' test_schema.test_table'
@ -137,7 +140,8 @@ class TestViewDataTemplates(BaseTestGenerator):
nsp_name='test_schema',
data_type={'text': 'text', 'id': 'integer'},
pk_names=None,
has_oids=True
has_oids=True,
type_cast_required={'text': 'True', 'id': 'True'}
),
insert_expected_return_value='INSERT INTO'
' test_schema.test_table'

View File

@ -12,6 +12,8 @@ from collections import OrderedDict
from pgadmin.tools.sqleditor.utils.constant_definition import TX_STATUS_IDLE
ignore_type_cast_list = ['character', 'character[]', 'bit', 'bit[]']
def save_changed_data(changed_data, columns_info, conn, command_obj,
client_primary_key, auto_commit=True):
@ -63,6 +65,7 @@ def save_changed_data(changed_data, columns_info, conn, command_obj,
column_type = {}
column_data = {}
type_cast_required = {}
for each_col in columns_info:
if (
columns_info[each_col]['not_null'] and
@ -75,6 +78,10 @@ def save_changed_data(changed_data, columns_info, conn, command_obj,
column_type[each_col] = \
columns_info[each_col]['type_name']
type_cast_required[each_col] = \
True if column_type[each_col] not in ignore_type_cast_list \
else False
# For newly added rows
if of_type == 'added':
# Python dict does not honour the inserted item order
@ -123,7 +130,8 @@ def save_changed_data(changed_data, columns_info, conn, command_obj,
nsp_name=command_obj.nsp_name,
data_type=column_type,
pk_names=pk_names,
has_oids=command_obj.has_oids()
has_oids=command_obj.has_oids(),
type_cast_required=type_cast_required
)
select_sql = render_template(
@ -161,7 +169,8 @@ def save_changed_data(changed_data, columns_info, conn, command_obj,
primary_keys=pk_escaped,
object_name=command_obj.object_name,
nsp_name=command_obj.nsp_name,
data_type=column_type
data_type=column_type,
type_cast_required=type_cast_required
)
list_of_sql[of_type].append({'sql': sql,
'data': data,

View File

@ -31,7 +31,9 @@ class TestSaveChangedData(BaseTestGenerator):
"data": {
"pk_col": "3",
"__temp_PK": "2",
"normal_col": "three"
"normal_col": "three",
"char_col": "char",
"bit_col": "10101"
}
}
},
@ -52,8 +54,86 @@ class TestSaveChangedData(BaseTestGenerator):
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False},
{"name": "normal_col",
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}
]
},
save_status=True,
check_sql='SELECT * FROM %s WHERE pk_col = 3',
check_result=[[3, "three", "char", "10101"]]
)),
('When inserting row with long value for character varying data type',
dict(
save_payload={
"updated": {},
"added": {
"2": {
"err": False,
"data": {
"pk_col": "3",
"__temp_PK": "2",
"normal_col": "invalid-log-string"
}
}
},
"staged_rows": {},
"deleted": {},
"updated_index": {},
"added_index": {"2": "2"},
"columns": [{
"name": "pk_col",
"display_name": "pk_col",
"column_type": "[PK] integer",
"column_type_internal": "integer",
"pos": 0,
"label": "pk_col<br>[PK] integer",
"cell": "number",
"can_edit": True,
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
@ -64,14 +144,39 @@ class TestSaveChangedData(BaseTestGenerator):
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False}
]
},
save_status=True,
check_sql='SELECT * FROM %s WHERE pk_col = 3',
check_result=[[3, "three"]]
)),
('When inserting row with long data', dict(
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}]
},
save_status=False,
check_sql='SELECT * FROM %s WHERE pk_col = 3',
check_result='SELECT 0')),
('When inserting row with long value for character data type', dict(
save_payload={
"updated": {},
"added": {
@ -80,7 +185,7 @@ class TestSaveChangedData(BaseTestGenerator):
"data": {
"pk_col": "3",
"__temp_PK": "2",
"normal_col": "invalid-log-string"
"char_col": "invalid long string"
}
}
},
@ -101,19 +206,124 @@ class TestSaveChangedData(BaseTestGenerator):
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False},
{"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False}
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}
]
},
save_status=False,
check_sql='SELECT * FROM %s WHERE pk_col = 3',
check_result='SELECT 0'
)),
('When inserting row with long value for bit data type', dict(
save_payload={
"updated": {},
"added": {
"2": {
"err": False,
"data": {
"pk_col": "3",
"__temp_PK": "2",
"bit_col": "1010101010"
}
}
},
"staged_rows": {},
"deleted": {},
"updated_index": {},
"added_index": {"2": "2"},
"columns": [
{
"name": "pk_col",
"display_name": "pk_col",
"column_type": "[PK] integer",
"column_type_internal": "integer",
"pos": 0,
"label": "pk_col<br>[PK] integer",
"cell": "number",
"can_edit": True,
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}
]
},
save_status=False,
@ -150,19 +360,47 @@ class TestSaveChangedData(BaseTestGenerator):
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False},
{"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False}
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}
]
},
save_status=False,
@ -198,55 +436,82 @@ class TestSaveChangedData(BaseTestGenerator):
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False},
{"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False}
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}
]
},
save_status=True,
check_sql='SELECT * FROM %s WHERE pk_col = 1',
check_result=[[1, "ONE"]]
check_result=[[1, "ONE", 'ch1 ', '00000']]
)),
('When updating a row in a invalid way', dict(
save_payload={
"updated": {
"1":
{"err": False,
"data": {"normal_col": "INVALID-COL-LENGTH"},
"primary_keys":
{"pk_col": 1}
}
},
"added": {},
"staged_rows": {},
"deleted": {},
"updated_index": {"1": "1"},
"added_index": {},
"columns": [
{
"name": "pk_col",
"display_name": "pk_col",
"column_type": "[PK] integer",
"column_type_internal": "integer",
"pos": 0,
"label": "pk_col<br>[PK] integer",
"cell": "number",
"can_edit": True,
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False},
{"name": "normal_col",
('When updating a row with long data for character varying data type',
dict(
save_payload={
"updated": {
"1": {"err": False,
"data": {"normal_col": "INVALID-COL-LENGTH"},
"primary_keys": {"pk_col": 1}
}
},
"added": {},
"staged_rows": {},
"deleted": {},
"updated_index": {"1": "1"},
"added_index": {},
"columns": [{
"name": "pk_col",
"display_name": "pk_col",
"column_type": "[PK] integer",
"column_type_internal": "integer",
"pos": 0,
"label": "pk_col<br>[PK] integer",
"cell": "number",
"can_edit": True,
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
@ -257,13 +522,191 @@ class TestSaveChangedData(BaseTestGenerator):
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False}
]
},
save_status=False,
check_sql='SELECT * FROM %s WHERE pk_col = 1',
check_result=[[1, "one"]]
)),
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}]
},
save_status=False,
check_sql='SELECT * FROM %s WHERE pk_col = 1',
check_result=[[1, "one", 'ch1 ', '00000']]
)),
('When updating a row with long data for character data type',
dict(
save_payload={
"updated": {
"1":
{"err": False,
"data": {"char_col": "INVALID-COL-LENGTH"},
"primary_keys":
{"pk_col": 1}
}
},
"added": {},
"staged_rows": {},
"deleted": {},
"updated_index": {"1": "1"},
"added_index": {},
"columns": [
{
"name": "pk_col",
"display_name": "pk_col",
"column_type": "[PK] integer",
"column_type_internal": "integer",
"pos": 0,
"label": "pk_col<br>[PK] integer",
"cell": "number",
"can_edit": True,
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}
]
},
save_status=False,
check_sql='SELECT * FROM %s WHERE pk_col = 1',
check_result=[[1, "one", 'ch1 ', '00000']]
)),
('When updating a row with long data for bit data type',
dict(
save_payload={
"updated": {
"1":
{"err": False,
"data": {"bit_col": "1010110101"},
"primary_keys":
{"pk_col": 1}
}
},
"added": {},
"staged_rows": {},
"deleted": {},
"updated_index": {"1": "1"},
"added_index": {},
"columns": [
{
"name": "pk_col",
"display_name": "pk_col",
"column_type": "[PK] integer",
"column_type_internal": "integer",
"pos": 0,
"label": "pk_col<br>[PK] integer",
"cell": "number",
"can_edit": True,
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}
]
},
save_status=False,
check_sql='SELECT * FROM %s WHERE pk_col = 1',
check_result=[[1, "one", 'ch1 ', '00000']]
)),
('When updating a row in an invalid way', dict(
save_payload={
"updated": {
@ -292,19 +735,47 @@ class TestSaveChangedData(BaseTestGenerator):
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False},
{"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False}
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}
]
},
save_status=False,
@ -333,19 +804,47 @@ class TestSaveChangedData(BaseTestGenerator):
"type": "integer",
"not_null": True,
"has_default_val": False,
"is_array": False},
{"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False}
"is_array": False
}, {
"name": "normal_col",
"display_name": "normal_col",
"column_type": "character varying",
"column_type_internal": "character varying",
"pos": 1,
"label": "normal_col<br>character varying",
"cell": "string",
"can_edit": True,
"type": "character varying",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "char_col",
"display_name": "normal_col",
"column_type": "character",
"column_type_internal": "character",
"pos": 2,
"label": "char_col<br>character",
"cell": "string",
"can_edit": True,
"type": "character",
"not_null": False,
"has_default_val": False,
"is_array": False
}, {
"name": "bit_col",
"display_name": "bit_col",
"column_type": "bit",
"column_type_internal": "bit",
"pos": 3,
"label": "bit_col<br>bit",
"cell": "string",
"can_edit": True,
"type": "bit",
"not_null": False,
"has_default_val": False,
"is_array": False
}
]
},
save_status=True,
@ -439,11 +938,13 @@ class TestSaveChangedData(BaseTestGenerator):
CREATE TABLE "%s"(
pk_col INT PRIMARY KEY,
normal_col VARCHAR(5));
normal_col character varying(5),
char_col character(4),
bit_col bit(5));
INSERT INTO "%s" VALUES
(1, 'one'),
(2, 'two');
(1, 'one', 'ch1', '00000'),
(2, 'two', 'ch2', '11111');
""" % (self.test_table_name,
self.test_table_name,
self.test_table_name)