     end
   end
 
-  defp encode_query_flags(values) when values == [] or map_size(values) == 0 do
-    <<0x00 ||| 0x04>>
-  end
-
-  defp encode_query_flags(values) when is_list(values) do
-    <<0x01 ||| 0x04>>
-  end
-
-  defp encode_query_flags(values) when is_map(values) do
-    <<0x01 ||| 0x04 ||| 0x40>>
-  end
-
-  defp encode_params(values, opts) do
+  defp set_query_values(mask, values) do
+    cond do
+      values == [] ->
+        mask
+      is_list(values) ->
+        mask ||| 0x01
+      map_size(values) == 0 ->
+        mask
+      is_map(values) ->
+        mask ||| 0x01 ||| 0x40
+    end
+  end
+
+  defp set_metadata_presence(mask, skip_metadata?) do
+    if skip_metadata? do
+      mask ||| 0x02
+    else
+      mask
+    end
+  end
+
+  defp encode_params(values, opts, skip_metadata?) do
     consistency = Keyword.get(opts, :consistency, :one)
     page_size = Keyword.get(opts, :page_size, 10_000)
 
+    flag_mask =
+      set_query_values(0x00, values)
+      |> bor(0x04)
+      |> set_metadata_presence(skip_metadata?)
+
     encode_consistency_level(consistency) <>
-      encode_query_flags(values) <>
+      <<flag_mask>> <>
       encode_values(values) <>
       <<page_size::32>>
   end


  def encode_query(statement, values, opts) do
    <<byte_size(statement)::32>> <> statement <>
      encode_params(values, opts)
  end

  def encode_prepared_query(id, values, opts) do
    <<byte_size(id)::16>> <> id <>
      encode_params(values, opts)
  end

  @consistency_levels %{

    decode_column_specs(rest, column_count - 1, nil, [entry | acc])
  end

  defp decode_column_specs(rest, column_count, table_spec, acc) do
    {keyspace_name, table_name} = table_spec
    {name, rest} = decode_string(rest)
    {type, rest} = decode_type(rest)
    entry = {keyspace_name, table_name, name, type}
    decode_column_specs(rest, column_count - 1, table_spec, [entry | acc])
  end

  defp decode_type(<<0x0000::16>> <> rest) do
