If I pass the filter {'id': [id1, id2, id3]} to db/sqlalchemy/api.py:volume_get_all(), it works as expected - returning only volumes whose ID is in the list. The same filter does not work for snapshot_get_all(), even though the code looks almost identical. Here is the stack trace (the error message in that mess is "Operand should contain 1 column(s)"):
2016-02-28 15:45:06.460 ERROR oslo_messaging._drivers.common [req-760caf24-40cd-45d8-96d7-12e660edf12a demo] ['Traceback (most recent call last
):\n', ' File "/usr/local/lib/python2.7/dist-packages/oslo_messaging/rpc/dispatcher.py", line 138, in _dispatch_and_reply\n incoming.messag
e))\n', ' File "/usr/local/lib/python2.7/dist-packages/oslo_messaging/rpc/dispatcher.py", line 183, in _dispatch\n return self._do_dispatch
(endpoint, method, ctxt, args)\n', ' File "/usr/local/lib/python2.7/dist-packages/oslo_messaging/rpc/dispatcher.py", line 127, in _do_dispatch
\n result = func(ctxt, **new_args)\n', ' File "/opt/stack/cinder/cinder/volume/manager.py", line 3538, in get_manageable_snapshots\n ret
urn self._get_manageable_resources(ctxt, \'snapshot\')\n', ' File "/opt/stack/cinder/cinder/volume/manager.py", line 2308, in _get_manageable_
resources\n LOG.exception(_LE("Listing manageable volumes failed, due to "\n', ' File "/usr/local/lib/python2.7/dist-packages/oslo_utils/ex
cutils.py", line 220, in __exit__\n self.force_reraise()\n', ' File "/usr/local/lib/python2.7/dist-packages/oslo_utils/excutils.py", line 1
96, in force_reraise\n six.reraise(self.type_, self.value, self.tb)\n', ' File "/opt/stack/cinder/cinder/volume/manager.py", line 2301, in
_get_manageable_resources\n ctxt, filters={\'id\': potential_ids})\n', ' File "/opt/stack/cinder/cinder/db/api.py", line 284, in snapshot_g
et_all\n sort_dirs, offset)\n', ' File "/opt/stack/cinder/cinder/db/sqlalchemy/api.py", line 175, in wrapper\n return f(*args, **kwargs)
\n', ' File "/opt/stack/cinder/cinder/db/sqlalchemy/api.py", line 2140, in snapshot_get_all\n return query.all()\n', ' File "/usr/local/li
b/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2588, in all\n return list(self)\n', ' File "/usr/local/lib/python2.7/dist-package
s/sqlalchemy/orm/query.py", line 2736, in __iter__\n return self._execute_and_instances(context)\n', ' File "/usr/local/lib/python2.7/dist-
packages/sqlalchemy/orm/query.py", line 2751, in _execute_and_instances\n result = conn.execute(querycontext.statement, self._params)\n', '
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 914, in execute\n return meth(self, multiparams, params)\n',
' File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/sql/elements.py", line 323, in _execute_on_connection\n return connection._execut
e_clauseelement(self, multiparams, params)\n', ' File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1010, in _execu
te_clauseelement\n compiled_sql, distilled_params\n', ' File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1146,
in _execute_context\n context)\n', ' File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1337, in _handle_dbapi_
exception\n util.raise_from_cause(newraise, exc_info)\n', ' File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/util/compat.py", line 2
00, in raise_from_cause\n reraise(type(exception), exception, tb=exc_tb, cause=cause)\n', ' File "/usr/local/lib/python2.7/dist-packages/sq
lalchemy/engine/base.py", line 1139, in _execute_context\n context)\n', ' File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/de
fault.py", line 450, in do_execute\n cursor.execute(statement, parameters)\n', ' File "/usr/local/lib/python2.7/dist-packages/pymysql/cursors.py", line 146, in execute\n result = self._query(query)\n', ' File "/usr/local/lib/python2.7/dist-packages/pymysql/cursors.py", line 296, in _query\n conn.query(q)\n', ' File "/usr/local/lib/python2.7/dist-packages/pymysql/connections.py", line 819, in query\n self._affected_rows = self._read_query_result(unbuffered=unbuffered)\n', ' File "/usr/local/lib/python2.7/dist-packages/pymysql/connections.py", line 1001, in _read_query_result\n result.read()\n', ' File "/usr/local/lib/python2.7/dist-packages/pymysql/connections.py", line 1285, in read\n first_packet = self.connection._read_packet()\n', ' File "/usr/local/lib/python2.7/dist-packages/pymysql/connections.py", line 965, in _read_packet\n packet.check_error()\n', ' File "/usr/local/lib/python2.7/dist-packages/pymysql/connections.py", line 394, in check_error\n err.raise_mysql_exception(self._data)\n', ' File "/usr/local/lib/python2.7/dist-packages/pymysql/err.py", line 120, in raise_mysql_exception\n _check_mysql_exception(errinfo)\n', ' File "/usr/local/lib/python2.7/dist-packages/pymysql/err.py", line 115, in _check_mysql_exception\n raise InternalError(errno, errorvalue)\n', "DBError: (pymysql.err.InternalError) (1241, u'Operand should contain 1 column(s)') [SQL: u'SELECT snapshots.created_at AS snapshots_created_at, snapshots.updated_at AS snapshots_updated_at, snapshots.deleted_at AS snapshots_deleted_at, snapshots.deleted AS snapshots_deleted, snapshots.id AS snapshots_id, snapshots.user_id AS snapshots_user_id, snapshots.project_id AS snapshots_project_id, snapshots.volume_id AS snapshots_volume_id, snapshots.cgsnapshot_id AS snapshots_cgsnapshot_id, snapshots.status AS snapshots_status, snapshots.progress AS snapshots_progress, snapshots.volume_size AS snapshots_volume_size, snapshots.display_name AS snapshots_display_name, snapshots.display_description AS snapshots_display_description, snapshots.encryption_key_id AS snapshots_encryption_key_id, snapshots.volume_type_id AS snapshots_volume_type_id, snapshots.provider_location AS snapshots_provider_location, snapshots.provider_id AS snapshots_provider_id, snapshots.provider_auth AS snapshots_provider_auth, snapshot_metadata_1.created_at AS snapshot_metadata_1_created_at, snapshot_metadata_1.updated_at AS snapshot_metadata_1_updated_at, snapshot_metadata_1.deleted_at AS snapshot_metadata_1_deleted_at, snapshot_metadata_1.deleted AS snapshot_metadata_1_deleted, snapshot_metadata_1.id AS snapshot_metadata_1_id, snapshot_metadata_1.`key` AS snapshot_metadata_1_key, snapshot_metadata_1.value AS snapshot_metadata_1_value, snapshot_metadata_1.snapshot_id AS snapshot_metadata_1_snapshot_id \\nFROM snapshots LEFT OUTER JOIN snapshot_metadata AS snapshot_metadata_1 ON snapshot_metadata_1.snapshot_id = snapshots.id AND snapshot_metadata_1.deleted = false \\nWHERE snapshots.deleted = false AND snapshots.id = %(id_1)s ORDER BY snapshots.created_at DESC, snapshots.id DESC'] [parameters: {u'id_1': ['05f459c4-bc19-45f6-b98f-33ccdc2e659e', '29ae5f66-a11e-4eae-abb1-1a1556381824']}]\n"]
For reference, the query generated for volumes:
SELECT volumes.created_at AS snapshot_ id, volumes.host AS volumes_host, volumes.size AS volumes_size, volumes.a availability_ zone, volumes.status AS volumes_status, volumes. attach_ status AS volumes_ attach_ status, volumes.migrat migration_ status, volumes. scheduled_ at AS volumes_ scheduled_ at, volumes.launched_at AS volumes_ launched_ at, volumes.termi terminated_ at, volumes. display_ name AS volumes_ display_ name, volumes. display_ description AS volumes_ display_ description, vo location AS volumes_ provider_ location, volumes. provider_ auth AS volumes_ provider_ auth, volumes. provider_ geometry AS volumes_prov provider_ id, volumes. volume_ type_id AS volumes_ volume_ type_id, volumes. source_ volid AS volumes_so encryption_ key_id AS volumes_ encryption_ key_id, volumes. consistencygrou p_id AS volumes_ consistencygrou p_id, volumes.bootabl multiattach, volumes. replication_ status AS volumes_ replication_ status, volumes.replicatio replication_ extended_ status, volumes. replication_ driver_ data AS volumes_ replication_ driver_ data, volumes.previous_ previous_ status, consistencygrou ps_1.created_ at AS consistencygrou ps_1_created_ at, consistencygrou ps_1.updated_ at AS consiste 1_updated_ at, consistencygrou ps_1.deleted_ at AS consistencygrou ps_1_deleted_ at, consistencygrou ps_1.deleted AS consistencygrou ps_1_de ps_1.id AS consistencygrou ps_1_id, consistencygrou ps_1.user_ id AS consistencygrou ps_1_user_ id, consistencygrou ps_1.projec ps_1_project_ id, consistencygrou ps_1.host AS consistencygrou ps_1_host, consistencygrou ps_1.availabili ty_zone AS consiste 1_availability_ zone, consistencygrou ps_1.name AS consistencygrou ps_1_name, consistencygrou ps_1.descriptio n AS consistencygrou ps_1_des ps_1.volume_ type_id AS consistencygrou ps_1_volume_ type_id, consistencygrou ps_1.status AS consistencygrou ps_1_status, c s_1.cgsnapshot_ id AS consistencygrou ps_1_cgsnapshot _id, consistencygrou ps_1.source_ cgid AS consistencygrou ps_1_source_ cgid, volu 1.created_ at AS volume_ attachment_ 1_created_ at, volume_ attachment_ 1.updated_ at AS volume_ attachment_ 1_updated_ at, volume_attachme attachment_ 1_deleted_ at, volume_ attachment_ 1.deleted AS volume_ attachment_ 1_deleted, volume_ attachment_ 1.id AS volume attachment_ 1.volume_ id AS volume_ attachment_ 1_volume_ id, volume_ attachment_ 1.instance_ uuid AS volume_ attachment_ 1_inst attachment_ 1.attached_ host AS volume_ attachment_ 1_attached_ host, volume_attach...
volumes_created_at, volumes.updated_at AS volumes_updated_at, volumes.deleted_at AS volumes_deleted_at, volumes.deleted AS volumes_deleted, vol
umes.id AS volumes_id, volumes._name_id AS volumes__name_id, volumes.ec2_id AS volumes_ec2_id, volumes.user_id AS volumes_user_id, volumes.proj
ect_id AS volumes_project_id, volumes.snapshot_id AS volumes_
vailability_zone AS volumes_
ion_status AS volumes_
nated_at AS volumes_
lumes.provider_
ider_geometry, volumes.provider_id AS volumes_
urce_volid, volumes.
e AS volumes_bootable, volumes.multiattach AS volumes_
n_extended_status AS volumes_
status AS volumes_
ncygroups_
leted, consistencygrou
t_id AS consistencygrou
ncygroups_
cription, consistencygrou
onsistencygroup
me_attachment_
nt_1.deleted_at AS volume_
_attachment_1_id, volume_
ance_uuid, volume_